mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-11-09 08:09:32 +08:00
refactor(components): update to use shadow DOM and work with css variables
- updates components to use shadow DOM or scoped if they require css variables - moves global styles to an external stylesheet that needs to be imported - adds support for additional colors and removes the Sass loops to generate colors for each component - several property renames, bug fixes, and test updates Co-authored-by: Manu Mtz.-Almeida <manu.mtza@gmail.com> Co-authored-by: Adam Bradley <adambradley25@gmail.com> Co-authored-by: Cam Wiegert <cam@camwiegert.com>
This commit is contained in:
@ -4,36 +4,28 @@
|
||||
// iOS Label
|
||||
// --------------------------------------------------
|
||||
|
||||
.label-ios {
|
||||
:host {
|
||||
@include margin($label-ios-margin-top, $label-ios-margin-end, $label-ios-margin-bottom, $label-ios-margin-start);
|
||||
|
||||
font-family: $label-ios-font-family;
|
||||
}
|
||||
|
||||
[text-wrap] .label-ios {
|
||||
:host([text-wrap]) {
|
||||
font-size: $label-ios-text-wrap-font-size;
|
||||
line-height: $label-ios-text-wrap-line-height;
|
||||
}
|
||||
|
||||
|
||||
// iOS Default Label Inside An Input/Select Item
|
||||
// --------------------------------------------------
|
||||
|
||||
.item-interactive .label-ios {
|
||||
color: $label-ios-text-color;
|
||||
}
|
||||
|
||||
|
||||
// iOS Stacked & Floating Labels
|
||||
// --------------------------------------------------
|
||||
|
||||
.label-ios-stacked {
|
||||
:host(.label-stacked) {
|
||||
@include margin(null, null, 4px, null);
|
||||
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.label-ios-floating {
|
||||
:host(.label-floating) {
|
||||
@include margin(null, null, 0, null);
|
||||
@include transform(translate3d(0, 27px, 0));
|
||||
@include transform-origin(start, top);
|
||||
@ -41,25 +33,64 @@
|
||||
transition: transform 150ms ease-in-out;
|
||||
}
|
||||
|
||||
.item-input-has-focus .label-ios-floating,
|
||||
.item-input-has-value .label-ios-floating {
|
||||
@include transform(translate3d(0, 0, 0), scale(.8));
|
||||
}
|
||||
|
||||
.item-input-has-focus .label-ios-stacked,
|
||||
.item-input-has-focus .label-ios-floating {
|
||||
:host-context(.item-has-focus).label-stacked,
|
||||
:host-context(.item-has-focus).label-floating {
|
||||
color: $label-ios-text-color-focused;
|
||||
}
|
||||
|
||||
|
||||
// Generate iOS Label colors
|
||||
// iOS Typography
|
||||
// --------------------------------------------------
|
||||
|
||||
@each $color-name, $color-value in $colors-ios {
|
||||
$color-base: ion-color($colors-ios, $color-name, base, ios);
|
||||
::slotted(*) h1 {
|
||||
@include margin(0, 0, 2px);
|
||||
|
||||
.label-ios-#{$color-name},
|
||||
.item-interactive .label-ios-#{$color-name} {
|
||||
color: $color-base;
|
||||
}
|
||||
font-size: 24px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
::slotted(*) h2 {
|
||||
@include margin(0, 0, 2px);
|
||||
|
||||
font-size: 17px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
::slotted(*) h3,
|
||||
::slotted(*) h4,
|
||||
::slotted(*) h5,
|
||||
::slotted(*) h6 {
|
||||
@include margin(0, 0, 3px);
|
||||
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
::slotted(*) p {
|
||||
@include margin($item-ios-paragraph-margin-top, $item-ios-paragraph-margin-end, $item-ios-paragraph-margin-bottom, $item-ios-paragraph-margin-start);
|
||||
|
||||
overflow: inherit;
|
||||
|
||||
font-size: $item-ios-paragraph-font-size;
|
||||
line-height: normal;
|
||||
text-overflow: inherit;
|
||||
}
|
||||
|
||||
::slotted(p) {
|
||||
color: #{$item-ios-paragraph-text-color};
|
||||
}
|
||||
|
||||
:host-context(.ion-color)::slotted(p) {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
|
||||
::slotted(*) h2:last-child,
|
||||
::slotted(*) h3:last-child,
|
||||
::slotted(*) h4:last-child,
|
||||
::slotted(*) h5:last-child,
|
||||
::slotted(*) h6:last-child,
|
||||
::slotted(*) p:last-child {
|
||||
@include margin(null, null, 0, null);
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
// --------------------------------------------------
|
||||
|
||||
/// @prop - Font family of the label
|
||||
$label-ios-font-family: $font-family-ios-base !default;
|
||||
$label-ios-font-family: $font-family-base !default;
|
||||
|
||||
/// @prop - Text color of the label by an input, select, or datetime
|
||||
$label-ios-text-color: null !default;
|
||||
@ -31,3 +31,6 @@ $label-ios-text-wrap-font-size: 14px !default;
|
||||
|
||||
/// @prop - Line height of the label when the text wraps
|
||||
$label-ios-text-wrap-line-height: 1.5 !default;
|
||||
|
||||
/// @prop - Color of the item paragraph
|
||||
$item-ios-paragraph-text-color: $text-color-step-600 !default;
|
||||
@ -4,13 +4,13 @@
|
||||
// Material Design Label
|
||||
// --------------------------------------------------
|
||||
|
||||
.label-md {
|
||||
:host {
|
||||
@include margin($label-md-margin-top, $label-md-margin-end, $label-md-margin-bottom, $label-md-margin-start);
|
||||
|
||||
font-family: $label-md-font-family;
|
||||
}
|
||||
|
||||
[text-wrap] .label-md {
|
||||
:host([text-wrap]) {
|
||||
font-size: $label-md-text-wrap-font-size;
|
||||
line-height: $label-md-text-wrap-line-height;
|
||||
}
|
||||
@ -19,49 +19,78 @@
|
||||
// Material Design Default Label Inside An Input/Select Item
|
||||
// --------------------------------------------------
|
||||
|
||||
.item-interactive .label-md {
|
||||
color: $label-md-text-color;
|
||||
// TODO, takes high priority
|
||||
:host-context(.item-interactive) {
|
||||
--ion-color-base: #{$label-md-text-color};
|
||||
}
|
||||
|
||||
|
||||
// Material Design Stacked & Floating Labels
|
||||
// --------------------------------------------------
|
||||
|
||||
.label-md-stacked {
|
||||
:host(.label-stacked) {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.label-md-floating {
|
||||
:host(.label-floating) {
|
||||
@include transform(translate3d(0, 27px, 0));
|
||||
@include transform-origin(start, top);
|
||||
|
||||
transition: transform 150ms ease-in-out;
|
||||
}
|
||||
|
||||
.label-md-stacked,
|
||||
.label-md-floating {
|
||||
:host(.label-stacked),
|
||||
:host(.label-floating) {
|
||||
@include margin(null, null, 0, 0);
|
||||
}
|
||||
|
||||
.item-input-has-focus .label-md-stacked,
|
||||
.item-input-has-focus .label-md-floating {
|
||||
:host-context(.item-has-focus).label-stacked,
|
||||
:host-context(.item-has-focus).label-floating {
|
||||
color: $label-md-text-color-focused;
|
||||
}
|
||||
|
||||
.item-input-has-focus .label-md-floating,
|
||||
.item-input-has-value .label-md-floating {
|
||||
@include transform(translate3d(0, 0, 0), scale(.8));
|
||||
}
|
||||
|
||||
|
||||
// Generate Material Design Label colors
|
||||
// MD Typography
|
||||
// --------------------------------------------------
|
||||
|
||||
@each $color-name, $color-value in $colors-md {
|
||||
$color-base: ion-color($colors-md, $color-name, base, md);
|
||||
::slotted(*) h1 {
|
||||
@include margin(0, 0, 2px);
|
||||
|
||||
.label-md-#{$color-name},
|
||||
.item-interactive .label-md-#{$color-name} {
|
||||
color: $color-base;
|
||||
}
|
||||
font-size: 24px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
::slotted(*) h2 {
|
||||
@include margin(2px, 0);
|
||||
|
||||
font-size: 16px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
::slotted(*) h3,
|
||||
::slotted(*) h4,
|
||||
::slotted(*) h5,
|
||||
::slotted(*) h6 {
|
||||
@include margin(2px, 0);
|
||||
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
::slotted(*) p {
|
||||
@include margin(0, 0, 2px);
|
||||
|
||||
overflow: inherit;
|
||||
|
||||
font-size: 14px;
|
||||
line-height: normal;
|
||||
text-overflow: inherit;
|
||||
}
|
||||
|
||||
::slotted(p) {
|
||||
color: #{$item-md-paragraph-text-color};
|
||||
}
|
||||
|
||||
:host-context(.ion-color)::slotted(p) {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
@ -6,13 +6,13 @@
|
||||
// --------------------------------------------------
|
||||
|
||||
/// @prop - Font family of the label
|
||||
$label-md-font-family: $font-family-md-base !default;
|
||||
$label-md-font-family: $font-family-base !default;
|
||||
|
||||
/// @prop - Text color of the label by an input, select, or datetime
|
||||
$label-md-text-color: $text-md-color-step-600 !default;
|
||||
$label-md-text-color: $text-color-step-600 !default;
|
||||
|
||||
/// @prop - Text color of the stacked/floating label when it is focused
|
||||
$label-md-text-color-focused: ion-color($colors-md, primary, base, md) !default;
|
||||
$label-md-text-color-focused: ion-color(primary, base) !default;
|
||||
|
||||
/// @prop - Margin top of the label
|
||||
$label-md-margin-top: $item-md-padding-top !default;
|
||||
@ -31,3 +31,6 @@ $label-md-text-wrap-font-size: 14px !default;
|
||||
|
||||
/// @prop - Line height of the label when the text wraps
|
||||
$label-md-text-wrap-line-height: 1.5 !default;
|
||||
|
||||
/// @prop - Color of the item paragraph
|
||||
$item-md-paragraph-text-color: $text-color-step-400 !default;
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
// Label
|
||||
// --------------------------------------------------
|
||||
|
||||
ion-label {
|
||||
:host {
|
||||
@include margin(0);
|
||||
|
||||
display: block;
|
||||
@ -15,9 +15,26 @@ ion-label {
|
||||
font-size: inherit;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
|
||||
box-sizing: border-box;
|
||||
|
||||
color: #{current-color(base)};
|
||||
|
||||
--ion-color-base: currentColor;
|
||||
}
|
||||
|
||||
.item-input ion-label {
|
||||
:host([text-wrap]) {
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
:host-context(.item-interactive-disabled) {
|
||||
cursor: default;
|
||||
opacity: .3;
|
||||
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
:host-context(.item-input) {
|
||||
flex: initial;
|
||||
|
||||
max-width: 200px;
|
||||
@ -25,15 +42,11 @@ ion-label {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
[text-wrap] ion-label {
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
|
||||
// Stacked & Floating Inputs
|
||||
// Fixed Inputs
|
||||
// --------------------------------------------------
|
||||
|
||||
.label-fixed {
|
||||
:host(.label-fixed) {
|
||||
flex: 0 0 100px;
|
||||
|
||||
width: 100px;
|
||||
@ -41,28 +54,20 @@ ion-label {
|
||||
max-width: 200px;
|
||||
}
|
||||
|
||||
.item-label-stacked ion-label,
|
||||
.item-label-floating ion-label {
|
||||
// Stacked & Floating Inputs
|
||||
// --------------------------------------------------
|
||||
|
||||
:host(.label-stacked),
|
||||
:host(.label-floating) {
|
||||
@include margin(null, null, 0, null);
|
||||
|
||||
align-self: stretch;
|
||||
|
||||
width: auto;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.label-stacked ,
|
||||
.label-floating {
|
||||
@include margin(null, null, 0, null);
|
||||
}
|
||||
|
||||
.item-label-stacked .input-wrapper,
|
||||
.item-label-floating .input-wrapper {
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.item-label-stacked ion-select,
|
||||
.item-label-floating ion-select {
|
||||
align-self: stretch;
|
||||
|
||||
max-width: 100%;
|
||||
:host-context(.item-has-focus).label-floating,
|
||||
:host-context(.item-has-value).label-floating {
|
||||
@include transform(translate3d(0, 0, 0), scale(.8));
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@ import {
|
||||
Watch
|
||||
} from '@stencil/core';
|
||||
import { Color, Mode, StyleEvent } from '../../interface';
|
||||
import { createColorClasses } from '../../utils/theme';
|
||||
|
||||
@Component({
|
||||
tag: 'ion-label',
|
||||
@ -15,9 +16,7 @@ import { Color, Mode, StyleEvent } from '../../interface';
|
||||
ios: 'label.ios.scss',
|
||||
md: 'label.md.scss'
|
||||
},
|
||||
host: {
|
||||
theme: 'label'
|
||||
}
|
||||
scoped: true
|
||||
})
|
||||
export class Label {
|
||||
@Element() el!: HTMLElement;
|
||||
@ -56,7 +55,8 @@ export class Label {
|
||||
@Watch('position')
|
||||
positionChanged() {
|
||||
const position = this.position;
|
||||
return this.ionStyle.emit({
|
||||
this.ionStyle.emit({
|
||||
'label': true,
|
||||
[`label-${position}`]: !!position
|
||||
});
|
||||
}
|
||||
@ -65,8 +65,8 @@ export class Label {
|
||||
const position = this.position;
|
||||
return {
|
||||
class: {
|
||||
...createColorClasses(this.color),
|
||||
[`label-${position}`]: !!position,
|
||||
[`label-${this.mode}-${position}`]: !!position
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,52 +1,48 @@
|
||||
<!DOCTYPE html>
|
||||
<html dir="ltr">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Label - Basic</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
|
||||
<script src="/dist/ionic.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/css/ionic.min.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<ion-app>
|
||||
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Label - Basic</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content>
|
||||
<ion-list>
|
||||
<ion-item>
|
||||
<ion-label>Default</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>
|
||||
<ion-item text-wrap>
|
||||
<ion-label>Wrap label this label just goes on and on and on</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label position="fixed">Fixed</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label position="floating">Floating</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label position="stacked">Stacked</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
</ion-content>
|
||||
|
||||
<style>
|
||||
img {
|
||||
height: 100px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Label - Basic</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content>
|
||||
<ion-list>
|
||||
<ion-item>
|
||||
<ion-label>Default</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label text-wrap>Wrap label this label just goes on and on and on</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label position="fixed">Fixed</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label position="floating">Floating</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label position="stacked">Stacked</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
</ion-content>
|
||||
</ion-app>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
@ -1,52 +1,48 @@
|
||||
<!DOCTYPE html>
|
||||
<html dir="ltr">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Label</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
|
||||
<script src="/dist/ionic.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/css/ionic.min.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<ion-app>
|
||||
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Label</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content>
|
||||
<ion-list>
|
||||
<ion-item>
|
||||
<ion-label>Default</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>
|
||||
<ion-item text-wrap>
|
||||
<ion-label>Wrap label this label just goes on and on and on</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label position="fixed">Fixed</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label position="floating">Floating</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label position="stacked">Stacked</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
</ion-content>
|
||||
|
||||
<style>
|
||||
img {
|
||||
height: 100px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Label</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content>
|
||||
<ion-list>
|
||||
<ion-item>
|
||||
<ion-label>Default</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label text-wrap>Wrap label this label just goes on and on and on</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label position="fixed">Fixed</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label position="floating">Floating</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label position="stacked">Stacked</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
</ion-content>
|
||||
</ion-app>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
<title>Label - Standalone</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
<script src="/dist/ionic.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/css/ionic.min.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
@ -4,8 +4,8 @@
|
||||
<ion-label>Default</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>
|
||||
<ion-item text-wrap>
|
||||
<ion-label>Wrap label this label just goes on and on and on</ion-label>
|
||||
<ion-item>
|
||||
<ion-label text-wrap>Wrap label this label just goes on and on and on</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
|
||||
Reference in New Issue
Block a user