Files
Bernardo Cardoso a5a7bee25c feat(tokens): update tokens architecture and usage (#29950)
Issue number: internal

---------

<!-- Please do not submit updates to dependencies unless it fixes an
issue. -->

<!-- Please try to limit your pull request to one type (bugfix, feature,
etc). Submit multiple pull requests if needed. -->


## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->

- Removed old tokens stored on foundations folder. Now the jsons with
the tokens come from the new dependency:
https://github.com/OutSystems/outsystems-design-tokens.
- The tokens from UX Team completely changed the structure and in some
cases the values. Everything was replaced on the project to use the new
tokens.
- Snapshots updated and differences reviewed with UX Team. A fix was
done on the testing css, to make sure the correct _Inter_ font-family
was actually used. This resulted in some differences on the text for
some componentes, that had snapshots with the native fonts.
- Removed generation of scss file on tokens script, that contained the
:root selector with the custom CSS properties, as they were not used on
the Ionic context.
- Removed generation of html file with tokens preview, as there wasn't a
great value on this (we have storybook on other contexts) and it allowed
to reduce a lot of code and complexity from the tokens script.
- The token command was adapted to use the command available from the
https://github.com/OutSystems/outsystems-design-tokens package, using
the `--config` prop, where we pass the path to our Ionic token script,
where we generate the needed scss variables and utility-classes (by
default the tokens repo tries to be as agnostic as possible, and only
generates the css variables, without the prefix and added details we
need on the Ionic side).
- Removed the token command from the npm run build, as it unnecessarily
added time on that command to run. Besides, it should not be common that
we need to run this command in the future.
- Updated reference to latest version of [Style Dictionary
4.1.3](https://v4.styledictionary.com/version-4/statement/). Version 4
comes with a lot of improvements, but also breaking-changes, so it was
needed to adapt the tokens script. The code on the script is also now
cleaner.
- Changed prefix from ionic to ion. The term ionic was used initially,
to help differentiate from the old ios/md stuff, but I feel with the
current scss architecture, that is no longer needed, and we can use the
same prefix across themes.

This requires to run `npm install ` again.

## Does this introduce a breaking change?

- [x] Yes
- [ ] No

<!--
  If this introduces a breaking change:
1. Describe the impact and migration path for existing applications
below.
  2. Update the BREAKING.md file with the breaking change.
3. Add "BREAKING CHANGE: [...]" to the commit description when merging.
See
https://github.com/ionic-team/ionic-framework/blob/main/docs/CONTRIBUTING.md#footer
for more information.
-->

---------

Co-authored-by: ionitron <hi@ionicframework.com>
Co-authored-by: Maria Hutt <thetaPC@users.noreply.github.com>
2024-10-28 18:17:48 +00:00

415 lines
9.9 KiB
SCSS

@use "../../themes/ionic/ionic.globals.scss" as globals;
// Ionic Checkbox
// --------------------------------------------------
:host {
// Border
--border-width: #{globals.$ion-border-size-025};
--border-style: #{globals.$ion-border-style-solid};
--border-color: #{globals.$ion-primitives-neutral-800};
--checkmark-width: #{globals.$ion-scale-400};
--checkmark-height: var(--checkmark-width);
// Focus
--focus-ring-color: #{globals.$ion-border-focus-default};
--focus-ring-width: #{globals.$ion-border-size-050};
--focus-ring-offset: #{globals.$ion-space-050};
// Size
--size: #{globals.$ion-scale-600};
--checkbox-background-checked: #{globals.$ion-semantics-primary-base};
--border-color-checked: #{globals.$ion-semantics-primary-base};
--checkmark-color: #{globals.$ion-primitives-base-white};
--transition: none;
display: inline-block;
position: relative;
cursor: pointer;
user-select: none;
z-index: 2;
// Checkbox Target area
// --------------------------------------------------
&::after {
@include globals.position(50%, 0, null, 0);
position: absolute;
height: 100%;
min-height: globals.$ion-scale-1200;
transform: translateY(-50%);
content: "";
cursor: pointer;
z-index: 1;
}
.native-wrapper {
position: relative;
}
}
:host(.in-item) {
flex: 1 1 0;
width: 100%;
height: 100%;
}
/**
* Checkbox can be slotted
* in components such as item and
* toolbar which is why we do not
* limit the below behavior to just ion-item.
*/
:host([slot="start"]),
:host([slot="end"]) {
// Reset the flex property when the checkbox
// is slotted to avoid growing the element larger
// than its content.
flex: initial;
width: auto;
}
.checkbox-wrapper {
display: flex;
flex-grow: 1;
align-items: center;
height: inherit;
cursor: inherit;
}
.label-text-wrapper {
color: globals.$ion-primitives-neutral-1200;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
:host(.in-item) .label-text-wrapper {
@include globals.margin(globals.$ion-space-250, null, globals.$ion-space-250, null);
}
:host(.in-item.checkbox-label-placement-stacked) .label-text-wrapper {
@include globals.margin(globals.$ion-space-250, null, globals.$ion-space-400, null);
}
:host(.in-item.checkbox-label-placement-stacked) .native-wrapper {
@include globals.margin(null, null, globals.$ion-space-250, null);
}
/**
* If no label text is placed into the slot
* then the element should be hidden otherwise
* there will be additional margins added.
*/
.label-text-wrapper-hidden {
display: none;
}
input {
@include globals.visually-hidden();
}
.native-wrapper {
@include globals.border-radius(var(--border-radius));
display: flex;
flex-shrink: 0;
align-items: center;
justify-content: center;
width: var(--size);
height: var(--size);
transition: var(--transition);
border-width: var(--border-width);
border-style: var(--border-style);
border-color: var(--border-color);
background: var(--checkbox-background);
box-sizing: border-box;
}
.checkbox-icon {
position: relative;
width: var(--checkmark-width);
height: var(--checkmark-height);
}
.checkbox-icon path {
fill: var(--checkmark-color);
opacity: 0;
}
// TODO move all justify and alignment styles to the common file
// when it is created
// Justify Content
// ---------------------------------------------
:host(.checkbox-justify-space-between) .checkbox-wrapper {
justify-content: space-between;
}
:host(.checkbox-justify-start) .checkbox-wrapper {
justify-content: start;
}
:host(.checkbox-justify-end) .checkbox-wrapper {
justify-content: end;
}
// Align Items
// ---------------------------------------------
:host(.checkbox-alignment-start) .checkbox-wrapper {
align-items: start;
}
:host(.checkbox-alignment-center) .checkbox-wrapper {
align-items: center;
}
// Justify Content & Align Items
// ---------------------------------------------
// The checkbox should be displayed as block when either justify
// or alignment is set; otherwise, these properties will have no
// visible effect.
:host(.checkbox-justify-space-between),
:host(.checkbox-justify-start),
:host(.checkbox-justify-end),
:host(.checkbox-alignment-start),
:host(.checkbox-alignment-center) {
display: block;
}
// Label Placement - Start
// ----------------------------------------------------------------
/**
* Label is on the left of the checkbox in LTR and
* on the right in RTL.
*/
:host(.checkbox-label-placement-start) .checkbox-wrapper {
flex-direction: row;
}
:host(.checkbox-label-placement-start) .label-text-wrapper {
/**
* The margin between the label and
* the checkbox should be on the end
* when the label sits at the start.
*/
@include globals.margin(null, globals.$ion-space-400, null, 0);
}
// Label Placement - End
// ----------------------------------------------------------------
/**
* Label is on the right of the checkbox in LTR and
* on the left in RTL.
*/
:host(.checkbox-label-placement-end) .checkbox-wrapper {
flex-direction: row-reverse;
}
/**
* The margin between the label and
* the checkbox should be on the start
* when the label sits at the end.
*/
:host(.checkbox-label-placement-end) .label-text-wrapper {
@include globals.margin(null, 0, null, globals.$ion-space-400);
}
// Label Placement - Fixed
// ----------------------------------------------------------------
:host(.checkbox-label-placement-fixed) .label-text-wrapper {
/**
* The margin between the label and
* the checkbox should be on the end
* when the label sits at the start.
*/
@include globals.margin(null, globals.$ion-space-400, null, 0);
}
/**
* Label is on the left of the checkbox in LTR and
* on the right in RTL. Label also has a fixed width.
*/
:host(.checkbox-label-placement-fixed) .label-text-wrapper {
flex: 0 0 100px;
width: 100px;
min-width: 100px;
max-width: 200px;
}
// Label Placement - Stacked
// ----------------------------------------------------------------
/**
* Label is on top of the checkbox.
*/
:host(.checkbox-label-placement-stacked) .checkbox-wrapper {
flex-direction: column;
}
:host(.checkbox-label-placement-stacked) .label-text-wrapper {
@include globals.transform(scale(0.75));
/**
* The margin between the label and
* the checkbox should be on the bottom
* when the label sits at the top.
*/
@include globals.margin(null, 0, globals.$ion-space-400, 0);
/**
* Label text should not extend
* beyond the bounds of the checkbox.
*/
max-width: calc(100% / 0.75);
}
// TODO(ROU-10796): uncomment this when the scss compilation issue is fixed
// :host(.checkbox-label-placement-stacked.checkbox-alignment-start) .label-text-wrapper {
// @include globals.transform-origin(start, top);
// }
// :host(.checkbox-label-placement-stacked.checkbox-alignment-center) .label-text-wrapper {
// @include globals.transform-origin(center, top);
// }
// Ionic Design Checkbox Sizes
// --------------------------------------------------
:host(.checkbox-size-small) {
--size: #{globals.$ion-scale-400};
}
// Checked / Indeterminate Checkbox
// ---------------------------------------------
:host(.checkbox-checked) .native-wrapper,
:host(.checkbox-indeterminate) .native-wrapper {
border-color: var(--border-color-checked);
background: var(--checkbox-background-checked);
}
:host(.checkbox-checked) .checkbox-icon path,
:host(.checkbox-indeterminate) .checkbox-icon path {
opacity: 1;
}
// Ionic Design Checkbox Invalid
// --------------------------------------------------
:host(.ion-invalid) {
--focus-ring-color: #{globals.$ion-border-focus-error};
.native-wrapper {
border-color: globals.$ion-semantics-danger-800;
}
}
// Checkbox Disabled
// --------------------------------------------------
:host(.checkbox-disabled) {
pointer-events: none;
}
// Checkbox overrides the disabled state mixin properties
// to fix positioning issues, as the top and left properties
// cause the overlay to start inside the border. We unset
// these position properties and inherit width and height to
// ensure the border is covered.
:host(.checkbox-disabled) .native-wrapper:after {
@include globals.disabled-state();
@include globals.position(unset, unset, unset, unset);
width: inherit;
height: inherit;
}
// disabled, checked checkbox
:host(.checkbox-disabled.checkbox-checked) .native-wrapper {
border-width: globals.$ion-border-size-0;
background-color: globals.$ion-semantics-primary-base;
}
// Checkbox Hover
// --------------------------------------------------------
@media (any-hover: hover) {
:host(:hover) .native-wrapper {
background-color: globals.$ion-primitives-neutral-100;
}
:host(:hover.checkbox-checked) .native-wrapper,
:host(:hover.checkbox-indeterminate) .native-wrapper {
background-color: globals.$ion-semantics-primary-800;
}
}
// Checkbox Focus
// --------------------------------------------------
// Only show the focus ring when the checkbox is focused and not disabled
:host(.ion-focused:not(.checkbox-disabled)) .native-wrapper {
outline: var(--focus-ring-width) globals.$ion-border-style-solid var(--focus-ring-color);
outline-offset: var(--focus-ring-offset);
}
// Checkbox: Active
// --------------------------------------------------------
:host(.ion-activated) .native-wrapper {
background-color: globals.$ion-primitives-neutral-200;
}
:host(.ion-activated.checkbox-checked) .native-wrapper,
:host(.ion-activated.checkbox-indeterminate) .native-wrapper {
background-color: globals.$ion-semantics-primary-900;
}
// Ionic Design Checkbox Shapes
// --------------------------------------------------
:host(.checkbox-shape-soft) {
--border-radius: #{globals.$ion-border-radius-100};
}
:host(.checkbox-size-small.checkbox-shape-soft) {
--border-radius: #{globals.$ion-border-radius-025};
}
:host(.checkbox-shape-rectangular) {
--border-radius: #{globals.$ion-border-radius-0};
}
.checkbox-wrapper {
min-height: #{globals.$ion-scale-1200};
}