Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a72f4f7a90 | ||
|
|
291beb32bb | ||
|
|
17e26d3312 | ||
|
|
7692398ca7 | ||
|
|
92920440fc |
@@ -3,7 +3,7 @@ description: 'Build Ionic Angular Server'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v5
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22.x
|
||||
- uses: ./.github/workflows/actions/download-archive
|
||||
|
||||
@@ -3,7 +3,7 @@ description: 'Build Ionic Angular'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v5
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22.x
|
||||
- uses: ./.github/workflows/actions/download-archive
|
||||
|
||||
@@ -9,7 +9,7 @@ runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v5
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22.x
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v5
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22.x
|
||||
- name: Install Dependencies
|
||||
|
||||
@@ -3,7 +3,7 @@ description: 'Build Ionic React Router'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v5
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22.x
|
||||
- uses: ./.github/workflows/actions/download-archive
|
||||
|
||||
@@ -3,7 +3,7 @@ description: 'Build Ionic React'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v5
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22.x
|
||||
- uses: ./.github/workflows/actions/download-archive
|
||||
|
||||
@@ -3,7 +3,7 @@ description: 'Builds Ionic Vue Router'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v5
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22.x
|
||||
- uses: ./.github/workflows/actions/download-archive
|
||||
|
||||
@@ -3,7 +3,7 @@ description: 'Build Ionic Vue'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v5
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22.x
|
||||
- uses: ./.github/workflows/actions/download-archive
|
||||
|
||||
@@ -19,7 +19,7 @@ inputs:
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v5
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22.x
|
||||
# Provenance requires npm 9.5.0+
|
||||
|
||||
@@ -6,7 +6,7 @@ inputs:
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v5
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22.x
|
||||
- uses: ./.github/workflows/actions/download-archive
|
||||
|
||||
@@ -3,7 +3,7 @@ description: 'Test Core Clean Build'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v5
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22.x
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ description: 'Test Core Lint'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v5
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22.x
|
||||
- name: Install Dependencies
|
||||
|
||||
@@ -13,7 +13,7 @@ inputs:
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v5
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22.x
|
||||
- uses: ./.github/workflows/actions/download-archive
|
||||
|
||||
@@ -6,7 +6,7 @@ inputs:
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v5
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22.x
|
||||
- name: Install Dependencies
|
||||
|
||||
@@ -6,7 +6,7 @@ inputs:
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v5
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22.x
|
||||
- uses: ./.github/workflows/actions/download-archive
|
||||
|
||||
@@ -6,7 +6,7 @@ inputs:
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v5
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22.x
|
||||
- uses: ./.github/workflows/actions/download-archive
|
||||
|
||||
@@ -6,7 +6,7 @@ inputs:
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v5
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22.x
|
||||
- uses: ./.github/workflows/actions/download-archive
|
||||
|
||||
@@ -7,7 +7,7 @@ on:
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v5
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22.x
|
||||
- uses: actions/download-artifact@v5
|
||||
|
||||
2
.github/workflows/assign-issues.yml
vendored
@@ -13,6 +13,6 @@ jobs:
|
||||
- name: 'Auto-assign issue'
|
||||
uses: pozil/auto-assign-issue@39c06395cbac76e79afc4ad4e5c5c6db6ecfdd2e # v2.2.0
|
||||
with:
|
||||
assignees: brandyscarney, thetaPC, ShaneK
|
||||
assignees: brandyscarney, ShaneK
|
||||
numOfAssignee: 1
|
||||
allowSelfAssign: false
|
||||
|
||||
2
.github/workflows/label.yml
vendored
@@ -13,7 +13,7 @@ jobs:
|
||||
triage:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/labeler@v6
|
||||
- uses: actions/labeler@v5
|
||||
with:
|
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
sync-labels: true
|
||||
|
||||
103
BREAKING.md
@@ -18,7 +18,6 @@ This is a comprehensive list of the breaking changes introduced in the major ver
|
||||
- [Button](#version-9x-button)
|
||||
- [Card](#version-9x-card)
|
||||
- [Chip](#version-9x-chip)
|
||||
- [Grid](#version-9x-grid)
|
||||
|
||||
<h2 id="version-9x-components">Components</h2>
|
||||
|
||||
@@ -33,105 +32,3 @@ This is a comprehensive list of the breaking changes introduced in the major ver
|
||||
<h4 id="version-9x-chip">Chip</h4>
|
||||
|
||||
- The `border-radius` of the `ios` and `md` chip now defaults to `10px` and `8px`, respectively, instead of `16px` in accordance with the iOS and Material Design 3 guidelines. To revert to the previous appearance, set the `shape` to `"round"`, or override the `--border-radius` CSS variable to specify a different value.
|
||||
|
||||
<h4 id="version-9x-grid">Grid</h4>
|
||||
|
||||
- The properties `pull` and `push` have been deprecated and no longer work. A similar look can be achieved with the newly added property `order`.
|
||||
|
||||
<h5>Example 1: Swap two columns</h5>
|
||||
|
||||
**Version up to 8.x**
|
||||
```html
|
||||
<ion-grid>
|
||||
<ion-row>
|
||||
<ion-col push="4">1</ion-col>
|
||||
<ion-col pull="4">2</ion-col>
|
||||
<ion-col>3</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
```
|
||||
**Version 9.x+**
|
||||
```html
|
||||
<ion-grid>
|
||||
<ion-row>
|
||||
<ion-col order="2">1</ion-col>
|
||||
<ion-col order="1">2</ion-col>
|
||||
<ion-col order="3">3</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
```
|
||||
|
||||
<h5>Example 2: Reorder columns with specific sizes</h5>
|
||||
To reorder two columns where column 1 has `size="9" push="3"` and column 2 has `size="3" pull="9"`:
|
||||
|
||||
**Version up to 8.x**
|
||||
```html
|
||||
<ion-grid>
|
||||
<ion-row>
|
||||
<ion-col push="3">1</ion-col>
|
||||
<ion-col pull="9">2</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
```
|
||||
**Version 9.x+**
|
||||
```html
|
||||
<ion-grid>
|
||||
<ion-row>
|
||||
<ion-col order="2">1</ion-col>
|
||||
<ion-col size="3" order="1">2</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
```
|
||||
<h5>Example 3: Push</h5>
|
||||
```html
|
||||
<ion-grid>
|
||||
<ion-row>
|
||||
<ion-col size="auto" push="1">
|
||||
<div>ion-col push 1</div>
|
||||
</ion-col>
|
||||
<ion-col size="auto" push="1">
|
||||
<div>ion-col push 1</div>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
```
|
||||
**Version 9.x+**
|
||||
```html
|
||||
<ion-grid>
|
||||
<ion-row>
|
||||
<ion-col size="auto" offset="1">
|
||||
<div>ion-col size="auto" offset="1"</div>
|
||||
</ion-col>
|
||||
<ion-col size="auto">
|
||||
<div>ion-col size="auto"</div>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
```
|
||||
|
||||
<h5>Example 4: Push and Pull</h5>
|
||||
```html
|
||||
<ion-grid>
|
||||
<ion-row>
|
||||
<ion-col size="3" size-md="6" push="9" push-md="6">
|
||||
<div>ion-col size="3" size-md="6" push="9" push-md="6"</div>
|
||||
</ion-col>
|
||||
<ion-col size="9" size-md="6" pull="3" pull-md="6">
|
||||
<div>ion-col size="9" size-md="6" pull="3" pull-md="6"</div>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
```
|
||||
**Version 9.x+**
|
||||
```html
|
||||
<ion-grid>
|
||||
<ion-row>
|
||||
<ion-col size="auto" order="2" order-md="2">
|
||||
<div>ion-col size="auto" order="2" order-md="2"</div>
|
||||
</ion-col>
|
||||
<ion-col size="auto" order="1" order-md="1">
|
||||
<div>ion-col size="auto" order="1" order-md="1"</div>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
```
|
||||
25
CHANGELOG.md
@@ -3,31 +3,6 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [8.7.5](https://github.com/ionic-team/ionic-framework/compare/v8.7.4...v8.7.5) (2025-09-24)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **modal:** allow sheet modals to skip focus trap ([#30689](https://github.com/ionic-team/ionic-framework/issues/30689)) ([a40d957](https://github.com/ionic-team/ionic-framework/commit/a40d957ad9c1897af365a91b45b00228a00d614c)), closes [#30684](https://github.com/ionic-team/ionic-framework/issues/30684)
|
||||
* **vue:** emit component-specific overlay events ([#30688](https://github.com/ionic-team/ionic-framework/issues/30688)) ([024d090](https://github.com/ionic-team/ionic-framework/commit/024d090122548e26ec2cdcfae4637dde8f288278)), closes [#30641](https://github.com/ionic-team/ionic-framework/issues/30641)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [8.7.4](https://github.com/ionic-team/ionic-framework/compare/v8.7.3...v8.7.4) (2025-09-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **input:** improve error text accessibility ([#30635](https://github.com/ionic-team/ionic-framework/issues/30635)) ([c339bc3](https://github.com/ionic-team/ionic-framework/commit/c339bc36827b62ef871325869a9a5db9b17ac785))
|
||||
* **overlays,picker:** remove invalid aria-hidden attribute ([#30563](https://github.com/ionic-team/ionic-framework/issues/30563)) ([49f96d7](https://github.com/ionic-team/ionic-framework/commit/49f96d7f1e9050a95e3e33a821c0467ecc0bed64)), closes [#30040](https://github.com/ionic-team/ionic-framework/issues/30040)
|
||||
* **segment-view:** scroll and select the right item when the component is in RTL context; ([#30675](https://github.com/ionic-team/ionic-framework/issues/30675)) ([66f517d](https://github.com/ionic-team/ionic-framework/commit/66f517d5b2154fff00b294a78f4107f057a580c6)), closes [#30079](https://github.com/ionic-team/ionic-framework/issues/30079)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [8.7.3](https://github.com/ionic-team/ionic-framework/compare/v8.7.2...v8.7.3) (2025-08-20)
|
||||
|
||||
|
||||
|
||||
@@ -3,30 +3,6 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [8.7.5](https://github.com/ionic-team/ionic-framework/compare/v8.7.4...v8.7.5) (2025-09-24)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **modal:** allow sheet modals to skip focus trap ([#30689](https://github.com/ionic-team/ionic-framework/issues/30689)) ([a40d957](https://github.com/ionic-team/ionic-framework/commit/a40d957ad9c1897af365a91b45b00228a00d614c)), closes [#30684](https://github.com/ionic-team/ionic-framework/issues/30684)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [8.7.4](https://github.com/ionic-team/ionic-framework/compare/v8.7.3...v8.7.4) (2025-09-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **input:** improve error text accessibility ([#30635](https://github.com/ionic-team/ionic-framework/issues/30635)) ([c339bc3](https://github.com/ionic-team/ionic-framework/commit/c339bc36827b62ef871325869a9a5db9b17ac785))
|
||||
* **overlays,picker:** remove invalid aria-hidden attribute ([#30563](https://github.com/ionic-team/ionic-framework/issues/30563)) ([49f96d7](https://github.com/ionic-team/ionic-framework/commit/49f96d7f1e9050a95e3e33a821c0467ecc0bed64)), closes [#30040](https://github.com/ionic-team/ionic-framework/issues/30040)
|
||||
* **segment-view:** scroll and select the right item when the component is in RTL context; ([#30675](https://github.com/ionic-team/ionic-framework/issues/30675)) ([66f517d](https://github.com/ionic-team/ionic-framework/commit/66f517d5b2154fff00b294a78f4107f057a580c6)), closes [#30079](https://github.com/ionic-team/ionic-framework/issues/30079)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [8.7.3](https://github.com/ionic-team/ionic-framework/compare/v8.7.2...v8.7.3) (2025-08-20)
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Get Playwright
|
||||
FROM mcr.microsoft.com/playwright:v1.55.1
|
||||
FROM mcr.microsoft.com/playwright:v1.54.2
|
||||
|
||||
# Set the working directory
|
||||
WORKDIR /ionic
|
||||
|
||||
@@ -622,12 +622,6 @@ ion-col,prop,offsetMd,string | undefined,undefined,false,false
|
||||
ion-col,prop,offsetSm,string | undefined,undefined,false,false
|
||||
ion-col,prop,offsetXl,string | undefined,undefined,false,false
|
||||
ion-col,prop,offsetXs,string | undefined,undefined,false,false
|
||||
ion-col,prop,order,string | undefined,undefined,false,false
|
||||
ion-col,prop,orderLg,string | undefined,undefined,false,false
|
||||
ion-col,prop,orderMd,string | undefined,undefined,false,false
|
||||
ion-col,prop,orderSm,string | undefined,undefined,false,false
|
||||
ion-col,prop,orderXl,string | undefined,undefined,false,false
|
||||
ion-col,prop,orderXs,string | undefined,undefined,false,false
|
||||
ion-col,prop,pull,string | undefined,undefined,false,false
|
||||
ion-col,prop,pullLg,string | undefined,undefined,false,false
|
||||
ion-col,prop,pullMd,string | undefined,undefined,false,false
|
||||
@@ -647,7 +641,6 @@ ion-col,prop,sizeSm,string | undefined,undefined,false,false
|
||||
ion-col,prop,sizeXl,string | undefined,undefined,false,false
|
||||
ion-col,prop,sizeXs,string | undefined,undefined,false,false
|
||||
ion-col,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-col,css-prop,--col-unit-size
|
||||
ion-col,css-prop,--ion-grid-column-padding
|
||||
ion-col,css-prop,--ion-grid-column-padding-lg
|
||||
ion-col,css-prop,--ion-grid-column-padding-md
|
||||
@@ -2013,7 +2006,6 @@ ion-router-outlet,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-row,shadow
|
||||
ion-row,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-row,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-row,css-prop,--ion-grid-gap
|
||||
|
||||
ion-searchbar,scoped
|
||||
ion-searchbar,prop,animated,boolean,false,false,false
|
||||
|
||||
996
core/package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/core",
|
||||
"version": "8.7.5",
|
||||
"version": "8.7.3",
|
||||
"description": "Base components for Ionic",
|
||||
"keywords": [
|
||||
"ionic",
|
||||
@@ -32,7 +32,7 @@
|
||||
],
|
||||
"dependencies": {
|
||||
"@phosphor-icons/core": "^2.1.1",
|
||||
"@stencil/core": "4.38.0",
|
||||
"@stencil/core": "4.36.2",
|
||||
"ionicons": "^8.0.13",
|
||||
"tslib": "^2.1.0"
|
||||
},
|
||||
@@ -45,7 +45,7 @@
|
||||
"@clack/prompts": "^0.11.0",
|
||||
"@ionic/eslint-config": "^0.3.0",
|
||||
"@ionic/prettier-config": "^2.0.0",
|
||||
"@playwright/test": "^1.55.1",
|
||||
"@playwright/test": "^1.54.2",
|
||||
"@rollup/plugin-node-resolve": "^8.4.0",
|
||||
"@rollup/plugin-virtual": "^2.0.3",
|
||||
"@stencil/angular-output-target": "^0.10.0",
|
||||
@@ -66,12 +66,12 @@
|
||||
"fs-extra": "^9.0.1",
|
||||
"jest": "^29.7.0",
|
||||
"jest-cli": "^29.7.0",
|
||||
"outsystems-design-tokens": "^1.3.2",
|
||||
"outsystems-design-tokens": "^1.3.0",
|
||||
"prettier": "^2.8.8",
|
||||
"rollup": "^2.26.4",
|
||||
"sass": "^1.33.0",
|
||||
"serve": "^14.0.1",
|
||||
"style-dictionary": "^5.0.0",
|
||||
"style-dictionary": "^4.1.3",
|
||||
"stylelint": "^13.13.1",
|
||||
"stylelint-order": "^4.1.0"
|
||||
},
|
||||
@@ -80,7 +80,7 @@
|
||||
"build.css": "npm run css.sass && npm run css.minify",
|
||||
"build.debug": "npm run clean && stencil build --debug",
|
||||
"build.docs.json": "stencil build --docs-json dist/docs.json",
|
||||
"build.tokens": "node ./node_modules/outsystems-design-tokens/scripts/index.js --config ./scripts/tokens/index.mjs && npm run prettier.tokens",
|
||||
"build.tokens": "npx build.tokens --config scripts/tokens/index.js && npm run prettier.tokens",
|
||||
"clean": "node scripts/clean.js",
|
||||
"css.minify": "cleancss -O2 -o ./css/ionic.bundle.css ./css/ionic.bundle.css",
|
||||
"css.sass": "sass --embed-sources --style compressed src/css:./css",
|
||||
|
||||
201
core/scripts/tokens/index.js
Normal file
@@ -0,0 +1,201 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
// For generating Design Tokens, we use Style Dictionary for several reasons:
|
||||
// - It's prepared to easily generate tokens for multiple types of outputs (CSS, SCSS, iOS, Android, documentation, etc.).
|
||||
// - It also works very well out of the box with any kind of Design Tokens formats, like Figma Tokens, as well as APIs to adjust to more custom ones.
|
||||
// - It is probably the most well-known and widely used Design Tokens tool. It has also been regularly maintained for a long time.
|
||||
// - It can easily scale to different necessities we might have in the future.
|
||||
(async () => {
|
||||
const {
|
||||
generateShadowValue,
|
||||
generateFontSizeValue,
|
||||
generateFontFamilyValue,
|
||||
generateTypographyOutput,
|
||||
generateValue,
|
||||
generateColorUtilityClasses,
|
||||
generateDefaultSpaceUtilityClasses,
|
||||
generateSpaceUtilityClasses,
|
||||
removeConsecutiveRepeatedWords,
|
||||
setPrefixValue,
|
||||
generateRadiusUtilityClasses,
|
||||
generateBorderUtilityClasses,
|
||||
generateFontUtilityClasses,
|
||||
generateShadowUtilityClasses,
|
||||
generateUtilityClasses
|
||||
} = require('./utils.js');
|
||||
|
||||
const StyleDictionary = (await import('style-dictionary')).default;
|
||||
|
||||
// Set the prefix for variables and classes
|
||||
setPrefixValue('ion');
|
||||
|
||||
// Register a custom file header
|
||||
StyleDictionary.registerFileHeader({
|
||||
name: 'custom-header',
|
||||
fileHeader: async (defaultMessages = []) => {
|
||||
return [...defaultMessages, 'Do not edit directly, this file was auto-generated.'];
|
||||
},
|
||||
});
|
||||
|
||||
// SCSS variables format
|
||||
StyleDictionary.registerFormat({
|
||||
name: 'scssVariablesFormat',
|
||||
format: async function ({ dictionary, file }) {
|
||||
|
||||
console.log('Generating SCSS variables...');
|
||||
|
||||
const primitiveProperties = dictionary.allTokens.filter((prop) => prop.path[0] === 'primitives');
|
||||
const scaleProperties = dictionary.allTokens.filter((prop) => prop.path[0] === 'scale');
|
||||
const borderProperties = dictionary.allTokens.filter((prop) => prop.path[0] === 'border');
|
||||
const semanticsProperties = dictionary.allTokens.filter((prop) => prop.path[0] === 'semantics');
|
||||
const nonPrimitiveScaleBorderSemanticsProperties = dictionary.allTokens.filter(
|
||||
(prop) => !['primitives', 'scale', 'border', 'semantics'].includes(prop.path[0])
|
||||
);
|
||||
const typographyProperties = nonPrimitiveScaleBorderSemanticsProperties.filter((prop) => prop.$type === 'typography');
|
||||
const otherProperties = nonPrimitiveScaleBorderSemanticsProperties.filter((prop) => prop.$type !== 'typography');
|
||||
|
||||
// Order: primitives → semantics → scale → border → other → typography
|
||||
const sortedProperties = [
|
||||
...primitiveProperties,
|
||||
...semanticsProperties,
|
||||
...scaleProperties,
|
||||
...borderProperties,
|
||||
...otherProperties,
|
||||
...typographyProperties
|
||||
];
|
||||
|
||||
const prefixedVariables = sortedProperties.map((prop) => {
|
||||
// Remove consecutive repeated words from the token name, like border-border-color
|
||||
const propName = removeConsecutiveRepeatedWords(prop.name);
|
||||
|
||||
switch (prop.$type) {
|
||||
case 'boxShadow':
|
||||
return generateShadowValue(prop, propName);
|
||||
case 'fontFamilies':
|
||||
return generateFontFamilyValue(prop, propName, 'scss');
|
||||
case 'fontSizes':
|
||||
return generateFontSizeValue(prop, propName, 'scss');
|
||||
case 'typography':
|
||||
return generateTypographyOutput(prop, propName, true);
|
||||
default:
|
||||
return generateValue(prop, propName);
|
||||
}
|
||||
});
|
||||
|
||||
const fileHeader = await file.options.fileHeader();
|
||||
|
||||
return [
|
||||
`/*\n${fileHeader.join('\n')}\n*/`,
|
||||
'@use "../themes/functions.sizes" as font;\n',
|
||||
prefixedVariables.join('\n') + '\n',
|
||||
].join('\n');
|
||||
},
|
||||
});
|
||||
|
||||
// Create utility-classes
|
||||
StyleDictionary.registerFormat({
|
||||
name: 'cssUtilityClassesFormat',
|
||||
format: async function ({ dictionary, file }) {
|
||||
|
||||
console.log('Generating Utility-Classes...');
|
||||
|
||||
// Arrays to store specific utility classes
|
||||
const typographyUtilityClasses = [];
|
||||
const otherUtilityClasses = [];
|
||||
|
||||
// Generate utility classes for each token
|
||||
dictionary.allTokens.map((prop) => {
|
||||
|
||||
const tokenCategory = prop.attributes.category;
|
||||
|
||||
if (prop.$type === 'fontFamilies' || tokenCategory === 'scale' || tokenCategory === 'backdrop') {
|
||||
// Not creating for the tokens below, as they make no sense to exist as utility-classes.
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove consecutive repeated words from the token name, like border-border-color
|
||||
const propName = removeConsecutiveRepeatedWords(prop.name);
|
||||
|
||||
if (prop.$type === 'typography') {
|
||||
// Typography tokens are handled differently, as each might have a different tokenType
|
||||
return typographyUtilityClasses.push(generateTypographyOutput(prop, propName, false));
|
||||
|
||||
} else if (tokenCategory.startsWith('round') || tokenCategory.startsWith('rectangular') || tokenCategory.startsWith('soft')) {
|
||||
// Generate utility classes for border-radius shape tokens, as they have their own token json file, based on primitive tokens
|
||||
return otherUtilityClasses.push(generateRadiusUtilityClasses(propName));
|
||||
}
|
||||
|
||||
let utilityClass = '';
|
||||
switch (tokenCategory) {
|
||||
case 'color':
|
||||
case 'primitives':
|
||||
case 'semantics':
|
||||
case 'text':
|
||||
case 'bg':
|
||||
case 'icon':
|
||||
case 'state':
|
||||
utilityClass = generateColorUtilityClasses(prop, propName);
|
||||
break;
|
||||
case 'border':
|
||||
utilityClass = generateBorderUtilityClasses(prop, propName);
|
||||
break;
|
||||
case 'font':
|
||||
utilityClass = generateFontUtilityClasses(prop, propName);
|
||||
break;
|
||||
case 'space':
|
||||
utilityClass = generateSpaceUtilityClasses(prop, propName);
|
||||
break;
|
||||
case 'shadow':
|
||||
case 'elevation':
|
||||
utilityClass = generateShadowUtilityClasses(propName);
|
||||
break;
|
||||
default:
|
||||
utilityClass = generateUtilityClasses(tokenCategory, propName);
|
||||
}
|
||||
|
||||
return otherUtilityClasses.push(utilityClass);
|
||||
});
|
||||
|
||||
const defaultSpaceUtilityClasses = generateDefaultSpaceUtilityClasses();
|
||||
otherUtilityClasses.push(defaultSpaceUtilityClasses);
|
||||
|
||||
// Concatenate typography utility classes at the beginning
|
||||
const finalOutput = typographyUtilityClasses.concat(otherUtilityClasses).join('\n');
|
||||
|
||||
const fileHeader = await file.options.fileHeader();
|
||||
|
||||
return [
|
||||
`/*\n${fileHeader.join('\n')}\n*/`,
|
||||
'@import "./ionic.vars";\n@import "../themes/mixins";\n',
|
||||
finalOutput,
|
||||
].join('\n');
|
||||
},
|
||||
});
|
||||
|
||||
})();
|
||||
|
||||
// APPLY THE CONFIGURATION
|
||||
module.exports = {
|
||||
source: ["node_modules/outsystems-design-tokens/tokens/**/*.json"],
|
||||
platforms: {
|
||||
scss: {
|
||||
transformGroup: "scss",
|
||||
buildPath: './src/foundations/',
|
||||
files: [
|
||||
{
|
||||
destination: "ionic.vars.scss",
|
||||
format: "scssVariablesFormat",
|
||||
options: {
|
||||
fileHeader: `custom-header`,
|
||||
},
|
||||
},
|
||||
{
|
||||
destination: "ionic.utility.scss",
|
||||
format: "cssUtilityClassesFormat",
|
||||
options: {
|
||||
fileHeader: `custom-header`
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,188 +0,0 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
// For generating Design Tokens, we use Style Dictionary for several reasons:
|
||||
// - It's prepared to easily generate tokens for multiple types of outputs (CSS, SCSS, iOS, Android, documentation, etc.).
|
||||
// - It also works very well out of the box with any kind of Design Tokens formats, like Figma Tokens, as well as APIs to adjust to more custom ones.
|
||||
// - It is probably the most well-known and widely used Design Tokens tool. It has also been regularly maintained for a long time.
|
||||
// - It can easily scale to different necessities we might have in the future.
|
||||
import StyleDictionary from 'style-dictionary';
|
||||
|
||||
import * as utils from './utils.mjs';
|
||||
|
||||
const {
|
||||
generateShadowValue,
|
||||
generateFontSizeValue,
|
||||
generateFontFamilyValue,
|
||||
generateTypographyOutput,
|
||||
generateValue,
|
||||
generateColorUtilityClasses,
|
||||
generateDefaultSpaceUtilityClasses,
|
||||
generateSpaceUtilityClasses,
|
||||
removeConsecutiveRepeatedWords,
|
||||
setVariablePrefixValue,
|
||||
setClassesAndScssPrefixValue: setClassesPrefixValue,
|
||||
generateRadiusUtilityClasses,
|
||||
generateBorderUtilityClasses,
|
||||
generateFontUtilityClasses,
|
||||
generateShadowUtilityClasses,
|
||||
generateUtilityClasses
|
||||
} = utils;
|
||||
|
||||
const customHeader = `// Do not edit directly, this file was auto-generated.`;
|
||||
// Set the prefix for classes
|
||||
setClassesPrefixValue('ion');
|
||||
// Set the prefix for variables
|
||||
setVariablePrefixValue('token');
|
||||
|
||||
// SCSS variables format
|
||||
StyleDictionary.registerFormat({
|
||||
name: 'scssVariablesFormat',
|
||||
format: function ({ dictionary }) { // Use 'format' for Style Dictionary v3
|
||||
console.log('Generating SCSS variables...');
|
||||
|
||||
const primitiveProperties = dictionary.allTokens.filter((prop) => prop.path[0] === 'primitives');
|
||||
const scaleProperties = dictionary.allTokens.filter((prop) => prop.path[0] === 'scale');
|
||||
const borderProperties = dictionary.allTokens.filter((prop) => prop.path[0] === 'border');
|
||||
const semanticsProperties = dictionary.allTokens.filter((prop) => prop.path[0] === 'semantics');
|
||||
const nonPrimitiveScaleBorderSemanticsProperties = dictionary.allTokens.filter(
|
||||
(prop) => !['primitives', 'scale', 'border', 'semantics'].includes(prop.path[0])
|
||||
);
|
||||
const typographyProperties = nonPrimitiveScaleBorderSemanticsProperties.filter((prop) => prop.$type === 'typography');
|
||||
const otherProperties = nonPrimitiveScaleBorderSemanticsProperties.filter((prop) => prop.$type !== 'typography');
|
||||
|
||||
// Order: primitives → semantics → scale → border → other → typography
|
||||
const sortedProperties = [
|
||||
...primitiveProperties,
|
||||
...semanticsProperties,
|
||||
...scaleProperties,
|
||||
...borderProperties,
|
||||
...otherProperties,
|
||||
...typographyProperties
|
||||
];
|
||||
|
||||
const prefixedVariables = sortedProperties.map((prop) => {
|
||||
// Remove consecutive repeated words from the token name, like border-border-color
|
||||
const propName = removeConsecutiveRepeatedWords(prop.name);
|
||||
|
||||
switch (prop.$type) {
|
||||
case 'boxShadow':
|
||||
return generateShadowValue(prop, propName);
|
||||
case 'fontFamilies':
|
||||
return generateFontFamilyValue(prop, propName, 'scss');
|
||||
case 'fontSizes':
|
||||
return generateFontSizeValue(prop, propName, 'scss');
|
||||
case 'typography':
|
||||
return generateTypographyOutput(prop, propName, true);
|
||||
default:
|
||||
return generateValue(prop, propName);
|
||||
}
|
||||
});
|
||||
|
||||
// In v3, the header is added automatically by Style Dictionary.
|
||||
// The format function should only return the file content.
|
||||
return [
|
||||
customHeader + '\n\n',
|
||||
'@use "../themes/functions.sizes" as font;\n',
|
||||
prefixedVariables.join('\n') + '\n',
|
||||
].join('');
|
||||
},
|
||||
});
|
||||
|
||||
// Create utility-classes
|
||||
StyleDictionary.registerFormat({
|
||||
name: 'cssUtilityClassesFormat',
|
||||
format: function ({ dictionary }) { // Use 'format' for Style Dictionary v3
|
||||
console.log('Generating Utility-Classes...');
|
||||
|
||||
// Arrays to store specific utility classes
|
||||
const typographyUtilityClasses = [];
|
||||
const otherUtilityClasses = [];
|
||||
|
||||
// Generate utility classes for each token
|
||||
dictionary.allTokens.map((prop) => {
|
||||
const tokenCategory = prop.attributes.category;
|
||||
|
||||
if (prop.$type === 'fontFamilies' || tokenCategory === 'scale' || tokenCategory === 'backdrop') {
|
||||
// Not creating for the tokens below, as they make no sense to exist as utility-classes.
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove consecutive repeated words from the token name, like border-border-color
|
||||
const propName = removeConsecutiveRepeatedWords(prop.name);
|
||||
|
||||
if (prop.$type === 'typography') {
|
||||
// Typography tokens are handled differently, as each might have a different tokenType
|
||||
return typographyUtilityClasses.push(generateTypographyOutput(prop, propName, false));
|
||||
} else if (tokenCategory.startsWith('round') || tokenCategory.startsWith('rectangular') || tokenCategory.startsWith('soft')) {
|
||||
// Generate utility classes for border-radius shape tokens, as they have their own token json file, based on primitive tokens
|
||||
return otherUtilityClasses.push(generateRadiusUtilityClasses(propName));
|
||||
}
|
||||
|
||||
let utilityClass = '';
|
||||
switch (tokenCategory) {
|
||||
case 'color':
|
||||
case 'primitives':
|
||||
case 'semantics':
|
||||
case 'text':
|
||||
case 'bg':
|
||||
case 'icon':
|
||||
case 'state':
|
||||
utilityClass = generateColorUtilityClasses(prop, propName);
|
||||
break;
|
||||
case 'border':
|
||||
utilityClass = generateBorderUtilityClasses(prop, propName);
|
||||
break;
|
||||
case 'font':
|
||||
utilityClass = generateFontUtilityClasses(prop, propName);
|
||||
break;
|
||||
case 'space':
|
||||
utilityClass = generateSpaceUtilityClasses(prop, propName);
|
||||
break;
|
||||
case 'shadow':
|
||||
case 'elevation':
|
||||
utilityClass = generateShadowUtilityClasses(propName);
|
||||
break;
|
||||
default:
|
||||
utilityClass = generateUtilityClasses(tokenCategory, propName);
|
||||
}
|
||||
|
||||
return otherUtilityClasses.push(utilityClass);
|
||||
});
|
||||
|
||||
const defaultSpaceUtilityClasses = generateDefaultSpaceUtilityClasses();
|
||||
otherUtilityClasses.push(defaultSpaceUtilityClasses);
|
||||
|
||||
// Concatenate typography utility classes at the beginning
|
||||
const finalOutput = typographyUtilityClasses.concat(otherUtilityClasses).join('\n');
|
||||
|
||||
// In v3, the header is added automatically by Style Dictionary.
|
||||
// The format function should only return the file content.
|
||||
return [
|
||||
customHeader + '\n\n',
|
||||
'@import "./ionic.vars";\n@import "../themes/mixins";\n',
|
||||
finalOutput,
|
||||
].join('');
|
||||
},
|
||||
});
|
||||
|
||||
// APPLY THE CONFIGURATION
|
||||
const config = {
|
||||
source: ["node_modules/outsystems-design-tokens/tokens/**/*.json"],
|
||||
platforms: {
|
||||
scss: {
|
||||
transformGroup: "scss",
|
||||
buildPath: './src/foundations/',
|
||||
files: [
|
||||
{
|
||||
destination: "ionic.vars.scss",
|
||||
format: "scssVariablesFormat",
|
||||
},
|
||||
{
|
||||
destination: "ionic.utility.scss",
|
||||
format: "cssUtilityClassesFormat",
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default config;
|
||||
335
core/scripts/tokens/utils.js
Normal file
@@ -0,0 +1,335 @@
|
||||
let variablesPrefix; // Variable that holds the prefix used on all css and scss variables generated
|
||||
|
||||
// Set the variable prefix value
|
||||
function setPrefixValue(prefix) {
|
||||
variablesPrefix = prefix;
|
||||
return variablesPrefix;
|
||||
}
|
||||
|
||||
// Generates a valid rgba() color
|
||||
function getRgbaValue(propValue) {
|
||||
// Check if its rgba color
|
||||
const isRgba = hexToRgba(propValue);
|
||||
// If it is, then compose rgba() color, otherwise use the normal color
|
||||
if (isRgba !== null) {
|
||||
return (propValue = `rgba(${isRgba.r}, ${isRgba.g}, ${isRgba.b},${isRgba.a})`);
|
||||
} else {
|
||||
return propValue;
|
||||
}
|
||||
}
|
||||
|
||||
// Translates an hex color value to rgb
|
||||
function hexToRgb(hex) {
|
||||
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
||||
return result
|
||||
? {
|
||||
r: parseInt(result[1], 16),
|
||||
g: parseInt(result[2], 16),
|
||||
b: parseInt(result[3], 16),
|
||||
}
|
||||
: null;
|
||||
}
|
||||
|
||||
// Translates an hex color value to rgba
|
||||
function hexToRgba(hex) {
|
||||
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
||||
return result
|
||||
? {
|
||||
r: parseInt(result[1], 16),
|
||||
g: parseInt(result[2], 16),
|
||||
b: parseInt(result[3], 16),
|
||||
a: Math.round((parseInt(result[4], 16) * 100) / 255) / 100,
|
||||
}
|
||||
: null;
|
||||
}
|
||||
|
||||
// Utility function to remove consecutive repeated words
|
||||
function removeConsecutiveRepeatedWords(str) {
|
||||
return str.replace(/(\b\w+\b)(-\1)+/g, '$1');
|
||||
}
|
||||
|
||||
// Generates a reference variable for an alias token type
|
||||
// (e.g., $ion-border-default: var(--ion-border-default, #d5d5d5) → $ion-border-default: var(--ion-border-default, $ion-primitives-neutral-400))
|
||||
function getAliasReferenceVariable(prop) {
|
||||
if (typeof prop.$value === 'string' && prop.$value.startsWith('{') && prop.$value.endsWith('}')) {
|
||||
// Remove curly braces and replace dots with dashes
|
||||
let ref = prop.$value.slice(1, -1).replace(/\./g, '-');
|
||||
// Remove consecutive repeated words (e.g., border-border-radius-0 → border-radius-0)
|
||||
ref = removeConsecutiveRepeatedWords(ref);
|
||||
return `$${variablesPrefix}-${ref}`;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Generates a valid box-shadow value from a shadow Design Token structure
|
||||
function generateShadowValue(prop, propName) {
|
||||
const cssShadow = prop.$value.map(shadow => {
|
||||
// Assuming shadow is an object with properties like offsetX, offsetY, blurRadius, spreadRadius, color
|
||||
const color = getRgbaValue(shadow.color);
|
||||
return `${shadow.x}px ${shadow.y}px ${shadow.blur}px ${shadow.spread}px ${color}`;
|
||||
}).join(', ');
|
||||
|
||||
return `$${variablesPrefix}-${propName}: var(--${variablesPrefix}-${propName}, ${cssShadow});`;
|
||||
}
|
||||
|
||||
// Generates a valid font-size value from a font-size Design Token structure, while transforming the pixels to rem
|
||||
function generateFontSizeValue(prop, propName, variableType = 'css') {
|
||||
return variableType === 'scss'
|
||||
? `$${variablesPrefix}-${propName}: var(--${variablesPrefix}-${propName}, font.px-to-rem(${parseInt(
|
||||
prop.$value
|
||||
)}));`
|
||||
: `--${propName}: #{font.px-to-rem(${parseInt(prop.$value)})};`;
|
||||
}
|
||||
|
||||
// Generates a valid font-family value from a font-family Design Token structure
|
||||
function generateFontFamilyValue(prop, propName, variableType = 'css') {
|
||||
// Remove the last word from the token, as it contains the name of the font, which we don't want to be included on the generated variables
|
||||
const _propName = propName.split('-').slice(0, -1).join('-');
|
||||
|
||||
return variableType === 'scss'
|
||||
? `$${variablesPrefix}-${_propName}: var(--${variablesPrefix}-${_propName}, "${prop.$value}", sans-serif);`
|
||||
: `--${variablesPrefix}-${_propName}: "${prop.$value}", sans-serif;`;
|
||||
}
|
||||
|
||||
// Generates a final value, based if the Design Token is of type color or not
|
||||
function generateValue(prop, propName) {
|
||||
// Use the original value to detect aliases
|
||||
const aliasVar = getAliasReferenceVariable({ $value: prop.original.$value });
|
||||
|
||||
// Always generate the main variable
|
||||
let mainValue;
|
||||
if (aliasVar) {
|
||||
mainValue = `$${variablesPrefix}-${propName}: var(--${variablesPrefix}-${propName}, ${aliasVar});`;
|
||||
} else {
|
||||
mainValue = `$${variablesPrefix}-${propName}: var(--${variablesPrefix}-${propName}, ${prop.$value});`;
|
||||
}
|
||||
|
||||
// Always generate the -rgb variable if it's a color
|
||||
const rgb = hexToRgb(prop.$value);
|
||||
let rgbDeclaration = '';
|
||||
if (rgb) {
|
||||
rgbDeclaration = `\n$${variablesPrefix}-${propName}-rgb: var(--${variablesPrefix}-${propName}-rgb, ${rgb.r}, ${rgb.g}, ${rgb.b});`;
|
||||
}
|
||||
|
||||
return `${mainValue}${rgbDeclaration}`;
|
||||
}
|
||||
|
||||
// Generates a typography based css utility-class or scss variable from a typography token structure
|
||||
function generateTypographyOutput(prop, propName, isVariable) {
|
||||
const typography = prop.original.$value;
|
||||
|
||||
// Extract the part after the last dot and trim any extraneous characters
|
||||
const extractLastPart = (str) => str.split('.').pop().replace(/[^\w-]/g, '');
|
||||
|
||||
const _initialWrapper = isVariable ? ': (' : ` {`;
|
||||
const _endWrapper = isVariable ? ')' : `}`;
|
||||
const _prefix = isVariable ? '$' : `.`;
|
||||
const _endChar = isVariable ? ',' : ';';
|
||||
|
||||
// This exact format is needed so that it compiles the tokens with the expected lint rules
|
||||
return `
|
||||
${_prefix}${variablesPrefix}-${propName}${_initialWrapper}
|
||||
font-size: $${variablesPrefix}-font-size-${extractLastPart(typography.fontSize)}${_endChar}
|
||||
font-style: ${prop.attributes.item?.toLowerCase() === 'italic' ? 'italic' : 'normal'}${_endChar}
|
||||
font-weight: $${variablesPrefix}-font-weight-${extractLastPart(typography.fontWeight)}${_endChar}
|
||||
letter-spacing: $${variablesPrefix}-font-letter-spacing-${extractLastPart(typography.letterSpacing) || 0}${_endChar}
|
||||
line-height: $${variablesPrefix}-font-line-height-${extractLastPart(typography.lineHeight)}${_endChar}
|
||||
text-transform: ${typography.textCase}${_endChar}
|
||||
text-decoration: ${typography.textDecoration}${_endChar}
|
||||
${_endWrapper};
|
||||
`;
|
||||
}
|
||||
|
||||
// Generates a color based css utility-class from a color Design Token structure
|
||||
function generateColorUtilityClasses(prop, className) {
|
||||
const isBg = className.includes('bg');
|
||||
const cssProp = isBg ? 'background-color' : 'color';
|
||||
return `.${variablesPrefix}-${className} {
|
||||
--${cssProp}: $${variablesPrefix}-${prop.name};
|
||||
${cssProp}: $${variablesPrefix}-${prop.name};
|
||||
}`;
|
||||
}
|
||||
|
||||
// Generates margin and padding utility classes to match the token-agnostic
|
||||
// utilities provided by the Ionic Framework
|
||||
function generateDefaultSpaceUtilityClasses() {
|
||||
const zeroMarginPaddingToken = 'space-0';
|
||||
const defaultMarginPaddingToken = 'space-400';
|
||||
|
||||
const marginPaddingTemplate = (type) => `
|
||||
.${variablesPrefix}-no-${type} {
|
||||
--${type}-top: #{$${variablesPrefix}-${zeroMarginPaddingToken}};
|
||||
--${type}-end: #{$${variablesPrefix}-${zeroMarginPaddingToken}};
|
||||
--${type}-bottom: #{$${variablesPrefix}-${zeroMarginPaddingToken}};
|
||||
--${type}-start: #{$${variablesPrefix}-${zeroMarginPaddingToken}};
|
||||
|
||||
@include ${type}($${variablesPrefix}-${zeroMarginPaddingToken});
|
||||
};
|
||||
|
||||
.${variablesPrefix}-${type} {
|
||||
--${type}-top: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
|
||||
--${type}-end: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
|
||||
--${type}-bottom: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
|
||||
--${type}-start: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
|
||||
|
||||
@include ${type}($${variablesPrefix}-${defaultMarginPaddingToken});
|
||||
};
|
||||
|
||||
.${variablesPrefix}-${type}-top {
|
||||
--${type}-top: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
|
||||
|
||||
@include ${type}($${variablesPrefix}-${defaultMarginPaddingToken}, null, null, null);
|
||||
};
|
||||
|
||||
.${variablesPrefix}-${type}-end {
|
||||
--${type}-end: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
|
||||
|
||||
@include ${type}(null, $${variablesPrefix}-${defaultMarginPaddingToken}, null, null);
|
||||
};
|
||||
|
||||
.${variablesPrefix}-${type}-bottom {
|
||||
--${type}-bottom: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
|
||||
|
||||
@include ${type}(null, null, $${variablesPrefix}-${defaultMarginPaddingToken}, null);
|
||||
};
|
||||
|
||||
.${variablesPrefix}-${type}-start {
|
||||
--${type}-start: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
|
||||
|
||||
@include ${type}(null, null, null, $${variablesPrefix}-${defaultMarginPaddingToken});
|
||||
};
|
||||
|
||||
.${variablesPrefix}-${type}-vertical {
|
||||
--${type}-top: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
|
||||
--${type}-bottom: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
|
||||
|
||||
@include ${type}($${variablesPrefix}-${defaultMarginPaddingToken}, null, $${variablesPrefix}-${defaultMarginPaddingToken}, null);
|
||||
};
|
||||
|
||||
.${variablesPrefix}-${type}-horizontal {
|
||||
--${type}-start: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
|
||||
--${type}-end: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
|
||||
|
||||
@include ${type}(null, $${variablesPrefix}-${defaultMarginPaddingToken}, null, $${variablesPrefix}-${defaultMarginPaddingToken});
|
||||
};
|
||||
`;
|
||||
|
||||
return `${marginPaddingTemplate('margin')}\n${marginPaddingTemplate('padding')}`;
|
||||
}
|
||||
|
||||
// Generates a margin or padding based css utility-class from a space Design Token structure
|
||||
function generateSpaceUtilityClasses(prop, className) {
|
||||
// This exact format is needed so that it compiles the tokens with the expected lint rules
|
||||
// It will generate classes for margin and padding, for equal sizing on all side and each direction
|
||||
const marginPaddingTemplate = (type) => `
|
||||
.${variablesPrefix}-${type}-${className} {
|
||||
--${type}-top: #{$${variablesPrefix}-${prop.name}};
|
||||
--${type}-end: #{$${variablesPrefix}-${prop.name}};
|
||||
--${type}-bottom: #{$${variablesPrefix}-${prop.name}};
|
||||
--${type}-start: #{$${variablesPrefix}-${prop.name}};
|
||||
|
||||
@include ${type}($${variablesPrefix}-${prop.name});
|
||||
};
|
||||
|
||||
.${variablesPrefix}-${type}-top-${className} {
|
||||
--${type}-top: #{$${variablesPrefix}-${prop.name}};
|
||||
|
||||
@include ${type}($${variablesPrefix}-${prop.name}, null, null, null);
|
||||
};
|
||||
|
||||
.${variablesPrefix}-${type}-end-${className} {
|
||||
--${type}-end: #{$${variablesPrefix}-${prop.name}};
|
||||
|
||||
@include ${type}(null, $${variablesPrefix}-${prop.name}, null, null);
|
||||
};
|
||||
|
||||
.${variablesPrefix}-${type}-bottom-${className} {
|
||||
--${type}-bottom: #{$${variablesPrefix}-${prop.name}};
|
||||
|
||||
@include ${type}(null, null, $${variablesPrefix}-${prop.name}, null);
|
||||
};
|
||||
|
||||
.${variablesPrefix}-${type}-start-${className} {
|
||||
--${type}-start: #{$${variablesPrefix}-${prop.name}};
|
||||
|
||||
@include ${type}(null, null, null, $${variablesPrefix}-${prop.name});
|
||||
};
|
||||
`;
|
||||
|
||||
// Add gap utility classes for gap tokens
|
||||
const generateGapUtilityClasses = () =>`
|
||||
.${variablesPrefix}-gap-${prop.name} {
|
||||
gap: #{$${variablesPrefix}-${prop.name}};
|
||||
};
|
||||
`;
|
||||
|
||||
return `${generateGapUtilityClasses()}\n${marginPaddingTemplate('margin')}\n${marginPaddingTemplate('padding')}`;
|
||||
}
|
||||
|
||||
// Generates a valid box-shadow value from a shadow Design Token structure
|
||||
function generateRadiusUtilityClasses(propName) {
|
||||
return `.${variablesPrefix}-${propName} {
|
||||
--border-radius: $${variablesPrefix}-${propName};
|
||||
border-radius: $${variablesPrefix}-${propName};
|
||||
}`;
|
||||
}
|
||||
|
||||
// Generates a border based css utility-class from a font Design Token structure
|
||||
function generateBorderUtilityClasses(prop, propName) {
|
||||
let attribute;
|
||||
|
||||
switch (prop.attributes.type) {
|
||||
case 'border-radius':
|
||||
case 'border-style':
|
||||
attribute = prop.attributes.type;
|
||||
break;
|
||||
case 'border-size':
|
||||
attribute = 'border-width';
|
||||
break;
|
||||
default:
|
||||
attribute = 'border-color';
|
||||
}
|
||||
return `.${variablesPrefix}-${propName} {
|
||||
--${attribute}: $${variablesPrefix}-${propName};
|
||||
${attribute}: $${variablesPrefix}-${propName};
|
||||
}`;
|
||||
}
|
||||
|
||||
// Generates a font based css utility-class from a font Design Token structure
|
||||
function generateFontUtilityClasses(prop, propName) {
|
||||
return `.${variablesPrefix}-${propName} {\n ${prop.attributes.type}: $${variablesPrefix}-${propName};\n}`;
|
||||
}
|
||||
|
||||
// Generates a valid box-shadow value from a shadow Design Token structure
|
||||
function generateShadowUtilityClasses(propName) {
|
||||
return `.${variablesPrefix}-${propName} {
|
||||
--box-shadow: $${variablesPrefix}-${propName};
|
||||
box-shadow: $${variablesPrefix}-${propName};
|
||||
}`;
|
||||
}
|
||||
|
||||
// Generates a utility class for a given token category and name
|
||||
function generateUtilityClasses(tokenCategory, propName){
|
||||
return `.${variablesPrefix}-${propName} {\n ${tokenCategory}: $${variablesPrefix}-${propName};\n}`;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getRgbaValue,
|
||||
hexToRgb,
|
||||
generateShadowValue,
|
||||
generateFontSizeValue,
|
||||
generateFontFamilyValue,
|
||||
generateTypographyOutput,
|
||||
generateValue,
|
||||
getAliasReferenceVariable,
|
||||
setPrefixValue,
|
||||
generateRadiusUtilityClasses,
|
||||
generateColorUtilityClasses,
|
||||
generateDefaultSpaceUtilityClasses,
|
||||
generateSpaceUtilityClasses,
|
||||
removeConsecutiveRepeatedWords,
|
||||
generateBorderUtilityClasses,
|
||||
generateFontUtilityClasses,
|
||||
generateShadowUtilityClasses,
|
||||
generateUtilityClasses
|
||||
};
|
||||
@@ -1,320 +0,0 @@
|
||||
let variablesPrefix; // Variable that holds the prefix used on all css variables generated
|
||||
let classAndScssPrefix; // Variable that holds the prefix used on all css utility-classes and scss variables generated
|
||||
|
||||
// Set the variable prefix value
|
||||
export function setVariablePrefixValue(prefix) {
|
||||
variablesPrefix = prefix;
|
||||
return variablesPrefix;
|
||||
}
|
||||
|
||||
export function setClassesAndScssPrefixValue(prefix) {
|
||||
classAndScssPrefix = prefix;
|
||||
return classAndScssPrefix;
|
||||
}
|
||||
|
||||
// Generates a valid rgba() color
|
||||
export function getRgbaValue(propValue) {
|
||||
// Check if its rgba color
|
||||
const isRgba = hexToRgba(propValue);
|
||||
// If it is, then compose rgba() color, otherwise use the normal color
|
||||
if (isRgba !== null) {
|
||||
return (propValue = `rgba(${isRgba.r}, ${isRgba.g}, ${isRgba.b},${isRgba.a})`);
|
||||
} else {
|
||||
return propValue;
|
||||
}
|
||||
}
|
||||
|
||||
// Translates an hex color value to rgb
|
||||
export function hexToRgb(hex) {
|
||||
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
||||
return result
|
||||
? {
|
||||
r: parseInt(result[1], 16),
|
||||
g: parseInt(result[2], 16),
|
||||
b: parseInt(result[3], 16),
|
||||
}
|
||||
: null;
|
||||
}
|
||||
|
||||
// Translates an hex color value to rgba
|
||||
function hexToRgba(hex) {
|
||||
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
||||
return result
|
||||
? {
|
||||
r: parseInt(result[1], 16),
|
||||
g: parseInt(result[2], 16),
|
||||
b: parseInt(result[3], 16),
|
||||
a: Math.round((parseInt(result[4], 16) * 100) / 255) / 100,
|
||||
}
|
||||
: null;
|
||||
}
|
||||
|
||||
// Utility function to remove consecutive repeated words
|
||||
export function removeConsecutiveRepeatedWords(str) {
|
||||
return str.replace(/(\b\w+\b)(-\1)+/g, '$1');
|
||||
}
|
||||
|
||||
// Generates a reference variable for an alias token type
|
||||
// (e.g., $ion-border-default: var(--ion-border-default, #d5d5d5) → $ion-border-default: var(--ion-border-default, $ion-primitives-neutral-400))
|
||||
export function getAliasReferenceVariable(prop) {
|
||||
if (typeof prop.$value === 'string' && prop.$value.startsWith('{') && prop.$value.endsWith('}')) {
|
||||
// Remove curly braces and replace dots with dashes
|
||||
let ref = prop.$value.slice(1, -1).replace(/\./g, '-');
|
||||
// Remove consecutive repeated words (e.g., border-border-radius-0 → border-radius-0)
|
||||
ref = removeConsecutiveRepeatedWords(ref);
|
||||
return `$${classAndScssPrefix}-${ref}`;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Generates a valid box-shadow value from a shadow Design Token structure
|
||||
export function generateShadowValue(prop, propName) {
|
||||
const cssShadow = prop.$value.map(shadow => {
|
||||
// Assuming shadow is an object with properties like offsetX, offsetY, blurRadius, spreadRadius, color
|
||||
const color = getRgbaValue(shadow.color);
|
||||
return `${shadow.x}px ${shadow.y}px ${shadow.blur}px ${shadow.spread}px ${color}`;
|
||||
}).join(', ');
|
||||
|
||||
return `$${classAndScssPrefix}-${propName}: var(--${variablesPrefix}-${propName}, ${cssShadow});`;
|
||||
}
|
||||
|
||||
// Generates a valid font-size value from a font-size Design Token structure, while transforming the pixels to rem
|
||||
export function generateFontSizeValue(prop, propName, variableType = 'css') {
|
||||
return variableType === 'scss'
|
||||
? `$${classAndScssPrefix}-${propName}: var(--${variablesPrefix}-${propName}, font.px-to-rem(${parseInt(
|
||||
prop.$value
|
||||
)}));`
|
||||
: `--${propName}: #{font.px-to-rem(${parseInt(prop.$value)})};`;
|
||||
}
|
||||
|
||||
// Generates a valid font-family value from a font-family Design Token structure
|
||||
export function generateFontFamilyValue(prop, propName, variableType = 'css') {
|
||||
// Remove the last word from the token, as it contains the name of the font, which we don't want to be included on the generated variables
|
||||
const _propName = propName.split('-').slice(0, -1).join('-');
|
||||
|
||||
return variableType === 'scss'
|
||||
? `$${classAndScssPrefix}-${_propName}: var(--${variablesPrefix}-${_propName}, ${prop.$value});`
|
||||
: `--${variablesPrefix}-${_propName}: ${prop.$value};`;
|
||||
}
|
||||
|
||||
// Generates a final value, based if the Design Token is of type color or not
|
||||
export function generateValue(prop, propName) {
|
||||
// Use the original value to detect aliases
|
||||
const aliasVar = getAliasReferenceVariable({ $value: prop.original.$value });
|
||||
|
||||
// Always generate the main variable
|
||||
let mainValue;
|
||||
if (aliasVar) {
|
||||
mainValue = `$${classAndScssPrefix}-${propName}: var(--${variablesPrefix}-${propName}, ${aliasVar});`;
|
||||
} else {
|
||||
mainValue = `$${classAndScssPrefix}-${propName}: var(--${variablesPrefix}-${propName}, ${prop.$value});`;
|
||||
}
|
||||
|
||||
// Always generate the -rgb variable if it's a color
|
||||
const rgb = hexToRgb(prop.$value);
|
||||
let rgbDeclaration = '';
|
||||
if (rgb) {
|
||||
rgbDeclaration = `\n$${classAndScssPrefix}-${propName}-rgb: var(--${variablesPrefix}-${propName}-rgb, ${rgb.r}, ${rgb.g}, ${rgb.b});`;
|
||||
}
|
||||
|
||||
return `${mainValue}${rgbDeclaration}`;
|
||||
}
|
||||
|
||||
// Generates a typography based css utility-class or scss variable from a typography token structure
|
||||
export function generateTypographyOutput(prop, propName, isVariable) {
|
||||
const typography = prop.original.$value;
|
||||
|
||||
// Extract the part after the last dot and trim any extraneous characters
|
||||
const extractLastPart = (str) => str.split('.').pop().replace(/[^\w-]/g, '');
|
||||
|
||||
const _initialWrapper = isVariable ? ': (' : ` {`;
|
||||
const _endWrapper = isVariable ? ')' : `}`;
|
||||
const _prefix = isVariable ? '$' : `.`;
|
||||
const _endChar = isVariable ? ',' : ';';
|
||||
|
||||
// This exact format is needed so that it compiles the tokens with the expected lint rules
|
||||
return `
|
||||
${_prefix}${classAndScssPrefix}-${propName}${_initialWrapper}
|
||||
font-size: $${classAndScssPrefix}-font-size-${extractLastPart(typography.fontSize)}${_endChar}
|
||||
font-style: ${prop.attributes.item?.toLowerCase() === 'italic' ? 'italic' : 'normal'}${_endChar}
|
||||
font-weight: $${classAndScssPrefix}-font-weight-${extractLastPart(typography.fontWeight)}${_endChar}
|
||||
letter-spacing: $${classAndScssPrefix}-font-letter-spacing-${extractLastPart(typography.letterSpacing) || 0}${_endChar}
|
||||
line-height: $${classAndScssPrefix}-font-line-height-${extractLastPart(typography.lineHeight)}${_endChar}
|
||||
text-transform: ${typography.textCase}${_endChar}
|
||||
text-decoration: ${typography.textDecoration}${_endChar}
|
||||
${_endWrapper};
|
||||
`;
|
||||
}
|
||||
|
||||
// Generates a color based css utility-class from a color Design Token structure
|
||||
export function generateColorUtilityClasses(prop, className) {
|
||||
const isBg = className.includes('bg');
|
||||
const cssProp = isBg ? 'background-color' : 'color';
|
||||
return `.${classAndScssPrefix}-${className} {
|
||||
--${cssProp}: #{$${classAndScssPrefix}-${prop.name}};
|
||||
${cssProp}: $${classAndScssPrefix}-${prop.name};
|
||||
}`;
|
||||
}
|
||||
|
||||
// Generates margin and padding utility classes to match the token-agnostic
|
||||
// utilities provided by the Ionic Framework
|
||||
export function generateDefaultSpaceUtilityClasses() {
|
||||
const zeroMarginPaddingToken = 'space-0';
|
||||
const defaultMarginPaddingToken = 'space-400';
|
||||
|
||||
const marginPaddingTemplate = (type) => `
|
||||
.${classAndScssPrefix}-no-${type} {
|
||||
--${type}-top: #{$${classAndScssPrefix}-${zeroMarginPaddingToken}};
|
||||
--${type}-end: #{$${classAndScssPrefix}-${zeroMarginPaddingToken}};
|
||||
--${type}-bottom: #{$${classAndScssPrefix}-${zeroMarginPaddingToken}};
|
||||
--${type}-start: #{$${classAndScssPrefix}-${zeroMarginPaddingToken}};
|
||||
|
||||
@include ${type}($${classAndScssPrefix}-${zeroMarginPaddingToken});
|
||||
};
|
||||
|
||||
.${classAndScssPrefix}-${type} {
|
||||
--${type}-top: #{$${classAndScssPrefix}-${defaultMarginPaddingToken}};
|
||||
--${type}-end: #{$${classAndScssPrefix}-${defaultMarginPaddingToken}};
|
||||
--${type}-bottom: #{$${classAndScssPrefix}-${defaultMarginPaddingToken}};
|
||||
--${type}-start: #{$${classAndScssPrefix}-${defaultMarginPaddingToken}};
|
||||
|
||||
@include ${type}($${classAndScssPrefix}-${defaultMarginPaddingToken});
|
||||
};
|
||||
|
||||
.${classAndScssPrefix}-${type}-top {
|
||||
--${type}-top: #{$${classAndScssPrefix}-${defaultMarginPaddingToken}};
|
||||
|
||||
@include ${type}($${classAndScssPrefix}-${defaultMarginPaddingToken}, null, null, null);
|
||||
};
|
||||
|
||||
.${classAndScssPrefix}-${type}-end {
|
||||
--${type}-end: #{$${classAndScssPrefix}-${defaultMarginPaddingToken}};
|
||||
|
||||
@include ${type}(null, $${classAndScssPrefix}-${defaultMarginPaddingToken}, null, null);
|
||||
};
|
||||
|
||||
.${classAndScssPrefix}-${type}-bottom {
|
||||
--${type}-bottom: #{$${classAndScssPrefix}-${defaultMarginPaddingToken}};
|
||||
|
||||
@include ${type}(null, null, $${classAndScssPrefix}-${defaultMarginPaddingToken}, null);
|
||||
};
|
||||
|
||||
.${classAndScssPrefix}-${type}-start {
|
||||
--${type}-start: #{$${classAndScssPrefix}-${defaultMarginPaddingToken}};
|
||||
|
||||
@include ${type}(null, null, null, $${classAndScssPrefix}-${defaultMarginPaddingToken});
|
||||
};
|
||||
|
||||
.${classAndScssPrefix}-${type}-vertical {
|
||||
--${type}-top: #{$${classAndScssPrefix}-${defaultMarginPaddingToken}};
|
||||
--${type}-bottom: #{$${classAndScssPrefix}-${defaultMarginPaddingToken}};
|
||||
|
||||
@include ${type}($${classAndScssPrefix}-${defaultMarginPaddingToken}, null, $${classAndScssPrefix}-${defaultMarginPaddingToken}, null);
|
||||
};
|
||||
|
||||
.${classAndScssPrefix}-${type}-horizontal {
|
||||
--${type}-start: #{$${classAndScssPrefix}-${defaultMarginPaddingToken}};
|
||||
--${type}-end: #{$${classAndScssPrefix}-${defaultMarginPaddingToken}};
|
||||
|
||||
@include ${type}(null, $${classAndScssPrefix}-${defaultMarginPaddingToken}, null, $${classAndScssPrefix}-${defaultMarginPaddingToken});
|
||||
};
|
||||
`;
|
||||
|
||||
return `${marginPaddingTemplate('margin')}\n${marginPaddingTemplate('padding')}`;
|
||||
}
|
||||
|
||||
// Generates a margin or padding based css utility-class from a space Design Token structure
|
||||
export function generateSpaceUtilityClasses(prop, className) {
|
||||
// This exact format is needed so that it compiles the tokens with the expected lint rules
|
||||
// It will generate classes for margin and padding, for equal sizing on all side and each direction
|
||||
const marginPaddingTemplate = (type) => `
|
||||
.${classAndScssPrefix}-${type}-${className} {
|
||||
--${type}-top: #{$${classAndScssPrefix}-${prop.name}};
|
||||
--${type}-end: #{$${classAndScssPrefix}-${prop.name}};
|
||||
--${type}-bottom: #{$${classAndScssPrefix}-${prop.name}};
|
||||
--${type}-start: #{$${classAndScssPrefix}-${prop.name}};
|
||||
|
||||
@include ${type}($${classAndScssPrefix}-${prop.name});
|
||||
};
|
||||
|
||||
.${classAndScssPrefix}-${type}-top-${className} {
|
||||
--${type}-top: #{$${classAndScssPrefix}-${prop.name}};
|
||||
|
||||
@include ${type}($${classAndScssPrefix}-${prop.name}, null, null, null);
|
||||
};
|
||||
|
||||
.${classAndScssPrefix}-${type}-end-${className} {
|
||||
--${type}-end: #{$${classAndScssPrefix}-${prop.name}};
|
||||
|
||||
@include ${type}(null, $${classAndScssPrefix}-${prop.name}, null, null);
|
||||
};
|
||||
|
||||
.${classAndScssPrefix}-${type}-bottom-${className} {
|
||||
--${type}-bottom: #{$${classAndScssPrefix}-${prop.name}};
|
||||
|
||||
@include ${type}(null, null, $${classAndScssPrefix}-${prop.name}, null);
|
||||
};
|
||||
|
||||
.${classAndScssPrefix}-${type}-start-${className} {
|
||||
--${type}-start: #{$${classAndScssPrefix}-${prop.name}};
|
||||
|
||||
@include ${type}(null, null, null, $${classAndScssPrefix}-${prop.name});
|
||||
};
|
||||
`;
|
||||
|
||||
// Add gap utility classes for gap tokens
|
||||
const generateGapUtilityClasses = () =>`
|
||||
.${classAndScssPrefix}-gap-${prop.name} {
|
||||
gap: #{$${classAndScssPrefix}-${prop.name}};
|
||||
};
|
||||
`;
|
||||
|
||||
return `${generateGapUtilityClasses()}\n${marginPaddingTemplate('margin')}\n${marginPaddingTemplate('padding')}`;
|
||||
}
|
||||
|
||||
// Generates a valid box-shadow value from a shadow Design Token structure
|
||||
export function generateRadiusUtilityClasses(propName) {
|
||||
return `.${classAndScssPrefix}-${propName} {
|
||||
--border-radius: #{$${classAndScssPrefix}-${propName}};
|
||||
border-radius: $${classAndScssPrefix}-${propName};
|
||||
}`;
|
||||
}
|
||||
|
||||
// Generates a border based css utility-class from a font Design Token structure
|
||||
export function generateBorderUtilityClasses(prop, propName) {
|
||||
let attribute;
|
||||
|
||||
switch (prop.attributes.type) {
|
||||
case 'border-radius':
|
||||
case 'border-style':
|
||||
attribute = prop.attributes.type;
|
||||
break;
|
||||
case 'border-size':
|
||||
attribute = 'border-width';
|
||||
break;
|
||||
default:
|
||||
attribute = 'border-color';
|
||||
}
|
||||
return `.${classAndScssPrefix}-${propName} {
|
||||
--${attribute}: #{$${classAndScssPrefix}-${propName}};
|
||||
${attribute}: $${classAndScssPrefix}-${propName};
|
||||
}`;
|
||||
}
|
||||
|
||||
// Generates a font based css utility-class from a font Design Token structure
|
||||
export function generateFontUtilityClasses(prop, propName) {
|
||||
return `.${classAndScssPrefix}-${propName} {\n ${prop.attributes.type}: $${classAndScssPrefix}-${propName};\n}`;
|
||||
}
|
||||
|
||||
// Generates a valid box-shadow value from a shadow Design Token structure
|
||||
export function generateShadowUtilityClasses(propName) {
|
||||
return `.${classAndScssPrefix}-${propName} {
|
||||
--box-shadow: #{$${classAndScssPrefix}-${propName}};
|
||||
box-shadow: $${classAndScssPrefix}-${propName};
|
||||
}`;
|
||||
}
|
||||
|
||||
// Generates a utility class for a given token category and name
|
||||
export function generateUtilityClasses(tokenCategory, propName){
|
||||
return `.${classAndScssPrefix}-${propName} {\n ${tokenCategory}: $${classAndScssPrefix}-${propName};\n}`;
|
||||
}
|
||||
72
core/src/components.d.ts
vendored
@@ -927,88 +927,52 @@ export namespace Components {
|
||||
* The amount to offset the column for xs screens, in terms of how many columns it should shift to the end of the total available.
|
||||
*/
|
||||
"offsetXs"?: string;
|
||||
/**
|
||||
* The order of the column, in terms of where the column should position itself in the columns renderer. If no value is passed, the column order implicit value will be the order in the html structure.
|
||||
*/
|
||||
"order"?: string;
|
||||
/**
|
||||
* The order of the column for lg screens, in terms of where the column should position itself in the columns renderer. If no value is passed, the column order implicit value will be the order in the html structure.
|
||||
*/
|
||||
"orderLg"?: string;
|
||||
/**
|
||||
* The order of the column for md screens, in terms of where the column should position itself in the columns renderer. If no value is passed, the column order implicit value will be the order in the html structure.
|
||||
*/
|
||||
"orderMd"?: string;
|
||||
/**
|
||||
* The order of the column for sm screens, in terms of where the column should position itself in the columns renderer. If no value is passed, the column order implicit value will be the order in the html structure.
|
||||
*/
|
||||
"orderSm"?: string;
|
||||
/**
|
||||
* The order of the column for xl screens, in terms of where the column should position itself in the columns renderer. If no value is passed, the column order implicit value will be the order in the html structure.
|
||||
*/
|
||||
"orderXl"?: string;
|
||||
/**
|
||||
* The order of the column for xs screens, in terms of where the column should position itself in the columns renderer. If no value is passed, the column order implicit value will be the order in the html structure.
|
||||
*/
|
||||
"orderXs"?: string;
|
||||
/**
|
||||
* The amount to pull the column, in terms of how many columns it should shift to the start of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pull"?: string;
|
||||
/**
|
||||
* The amount to pull the column for lg screens, in terms of how many columns it should shift to the start of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pullLg"?: string;
|
||||
/**
|
||||
* The amount to pull the column for md screens, in terms of how many columns it should shift to the start of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pullMd"?: string;
|
||||
/**
|
||||
* The amount to pull the column for sm screens, in terms of how many columns it should shift to the start of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pullSm"?: string;
|
||||
/**
|
||||
* The amount to pull the column for xl screens, in terms of how many columns it should shift to the start of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pullXl"?: string;
|
||||
/**
|
||||
* The amount to pull the column for xs screens, in terms of how many columns it should shift to the start of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pullXs"?: string;
|
||||
/**
|
||||
* The amount to push the column, in terms of how many columns it should shift to the end of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"push"?: string;
|
||||
/**
|
||||
* The amount to push the column for lg screens, in terms of how many columns it should shift to the end of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pushLg"?: string;
|
||||
/**
|
||||
* The amount to push the column for md screens, in terms of how many columns it should shift to the end of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pushMd"?: string;
|
||||
/**
|
||||
* The amount to push the column for sm screens, in terms of how many columns it should shift to the end of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pushSm"?: string;
|
||||
/**
|
||||
* The amount to push the column for xl screens, in terms of how many columns it should shift to the end of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pushXl"?: string;
|
||||
/**
|
||||
* The amount to push the column for xs screens, in terms of how many columns it should shift to the end of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pushXs"?: string;
|
||||
/**
|
||||
@@ -6897,88 +6861,52 @@ declare namespace LocalJSX {
|
||||
* The amount to offset the column for xs screens, in terms of how many columns it should shift to the end of the total available.
|
||||
*/
|
||||
"offsetXs"?: string;
|
||||
/**
|
||||
* The order of the column, in terms of where the column should position itself in the columns renderer. If no value is passed, the column order implicit value will be the order in the html structure.
|
||||
*/
|
||||
"order"?: string;
|
||||
/**
|
||||
* The order of the column for lg screens, in terms of where the column should position itself in the columns renderer. If no value is passed, the column order implicit value will be the order in the html structure.
|
||||
*/
|
||||
"orderLg"?: string;
|
||||
/**
|
||||
* The order of the column for md screens, in terms of where the column should position itself in the columns renderer. If no value is passed, the column order implicit value will be the order in the html structure.
|
||||
*/
|
||||
"orderMd"?: string;
|
||||
/**
|
||||
* The order of the column for sm screens, in terms of where the column should position itself in the columns renderer. If no value is passed, the column order implicit value will be the order in the html structure.
|
||||
*/
|
||||
"orderSm"?: string;
|
||||
/**
|
||||
* The order of the column for xl screens, in terms of where the column should position itself in the columns renderer. If no value is passed, the column order implicit value will be the order in the html structure.
|
||||
*/
|
||||
"orderXl"?: string;
|
||||
/**
|
||||
* The order of the column for xs screens, in terms of where the column should position itself in the columns renderer. If no value is passed, the column order implicit value will be the order in the html structure.
|
||||
*/
|
||||
"orderXs"?: string;
|
||||
/**
|
||||
* The amount to pull the column, in terms of how many columns it should shift to the start of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pull"?: string;
|
||||
/**
|
||||
* The amount to pull the column for lg screens, in terms of how many columns it should shift to the start of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pullLg"?: string;
|
||||
/**
|
||||
* The amount to pull the column for md screens, in terms of how many columns it should shift to the start of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pullMd"?: string;
|
||||
/**
|
||||
* The amount to pull the column for sm screens, in terms of how many columns it should shift to the start of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pullSm"?: string;
|
||||
/**
|
||||
* The amount to pull the column for xl screens, in terms of how many columns it should shift to the start of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pullXl"?: string;
|
||||
/**
|
||||
* The amount to pull the column for xs screens, in terms of how many columns it should shift to the start of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pullXs"?: string;
|
||||
/**
|
||||
* The amount to push the column, in terms of how many columns it should shift to the end of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"push"?: string;
|
||||
/**
|
||||
* The amount to push the column for lg screens, in terms of how many columns it should shift to the end of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pushLg"?: string;
|
||||
/**
|
||||
* The amount to push the column for md screens, in terms of how many columns it should shift to the end of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pushMd"?: string;
|
||||
/**
|
||||
* The amount to push the column for sm screens, in terms of how many columns it should shift to the end of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pushSm"?: string;
|
||||
/**
|
||||
* The amount to push the column for xl screens, in terms of how many columns it should shift to the end of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pushXl"?: string;
|
||||
/**
|
||||
* The amount to push the column for xs screens, in terms of how many columns it should shift to the end of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pushXs"?: string;
|
||||
/**
|
||||
|
||||
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.5 KiB |
@@ -366,6 +366,63 @@
|
||||
</div>
|
||||
</ion-list>
|
||||
|
||||
<ion-list id="tab-button-icon-bottom">
|
||||
<ion-list-header>
|
||||
<ion-label> Inside Tab Button - Only Icon </ion-label>
|
||||
</ion-list-header>
|
||||
|
||||
<div class="ion-display-flex ion-align-items-center ion-justify-content-around ion-margin">
|
||||
<ion-tab-bar>
|
||||
<ion-tab-button href="" tab="tab-one" layout="label-hide">
|
||||
<ion-icon name="home"></ion-icon>
|
||||
<ion-badge size="small" vertical="top" color="danger"></ion-badge>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab="schedule" class="e2eTabTwoButton" layout="label-hide">
|
||||
<ion-icon name="globe"></ion-icon>
|
||||
<ion-badge size="small" vertical="top" color="primary">
|
||||
<ion-icon name="star"></ion-icon>
|
||||
</ion-badge>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab="tab-three" layout="label-hide">
|
||||
<ion-icon name="logo-facebook"></ion-icon>
|
||||
<ion-badge size="small" vertical="top" color="warning">999</ion-badge>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab="tab-four" class="e2eTabFourButton" layout="label-hide">
|
||||
<ion-icon name="chatbox"></ion-icon>
|
||||
<ion-badge vertical="top" color="success" size="small"></ion-badge>
|
||||
</ion-tab-button>
|
||||
</ion-tab-bar>
|
||||
</div>
|
||||
<div class="ion-display-flex ion-align-items-center ion-justify-content-around ion-margin">
|
||||
<ion-tab-bar>
|
||||
<ion-tab-button href="" tab="tab-one" layout="label-hide">
|
||||
<ion-icon name="home"></ion-icon>
|
||||
<ion-badge size="small" vertical="bottom" color="danger"></ion-badge>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab="schedule" class="e2eTabTwoButton" layout="label-hide">
|
||||
<ion-icon name="globe"></ion-icon>
|
||||
<ion-badge size="small" vertical="bottom" color="primary">
|
||||
<ion-icon name="star"></ion-icon>
|
||||
</ion-badge>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab="tab-three" layout="label-hide">
|
||||
<ion-icon name="logo-facebook"></ion-icon>
|
||||
<ion-badge size="small" vertical="bottom" color="warning">999</ion-badge>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab="tab-four" class="e2eTabFourButton" layout="label-hide">
|
||||
<ion-icon name="chatbox"></ion-icon>
|
||||
<ion-badge vertical="bottom" color="success" size="small"></ion-badge>
|
||||
</ion-tab-button>
|
||||
</ion-tab-bar>
|
||||
</div>
|
||||
</ion-list>
|
||||
|
||||
<ion-list id="button-top">
|
||||
<ion-list-header>
|
||||
<ion-label> Inside Button - Top Placement </ion-label>
|
||||
|
||||
|
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 8.2 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
@@ -59,9 +59,9 @@
|
||||
:host(.button-outline) {
|
||||
--border-width: #{globals.$ion-border-size-025};
|
||||
--border-style: #{globals.$ion-border-style-solid};
|
||||
--background-activated: #{globals.ion-color(primary, shade, $subtle: true)};
|
||||
--background-activated: #{globals.$ion-bg-neutral-subtlest-press};
|
||||
--background-focused: transparent;
|
||||
--background-hover: #{globals.ion-color(primary, shade, $subtle: true)};
|
||||
--background-hover: #{globals.$ion-bg-neutral-subtlest-press};
|
||||
--background-hover-opacity: 1;
|
||||
--border-color: #{globals.ion-color(primary, base)};
|
||||
--color: #{globals.ion-color(primary, base)};
|
||||
@@ -69,20 +69,13 @@
|
||||
--ripple-color: var(--background-activated);
|
||||
}
|
||||
|
||||
// Warning Outline Button - use foreground color for text and border
|
||||
:host(.button-outline.ion-color-warning) .button-native {
|
||||
border-color: globals.ion-color(warning, foreground);
|
||||
|
||||
color: globals.ion-color(warning, foreground);
|
||||
}
|
||||
|
||||
// Clear Button
|
||||
// --------------------------------------------------
|
||||
|
||||
:host(.button-clear) {
|
||||
--background-activated: #{globals.ion-color(primary, shade, $subtle: true)};
|
||||
--background-activated: #{globals.$ion-bg-neutral-subtlest-press};
|
||||
--background-focused: transparent;
|
||||
--background-hover: #{globals.ion-color(primary, shade, $subtle: true)};
|
||||
--background-hover: #{globals.$ion-bg-neutral-subtlest-press};
|
||||
--background-hover-opacity: 1;
|
||||
--color: #{globals.ion-color(primary, foreground)};
|
||||
--ripple-opacity: var(--background-activated-opacity, 1);
|
||||
@@ -98,7 +91,7 @@
|
||||
|
||||
:host(.button-outline.ion-color) ion-ripple-effect,
|
||||
:host(.button-clear.ion-color) ion-ripple-effect {
|
||||
color: globals.current-color(shade, $subtle: true);
|
||||
color: globals.$ion-primitives-neutral-200;
|
||||
}
|
||||
|
||||
// Button Sizes
|
||||
@@ -185,21 +178,21 @@
|
||||
// --------------------------------------------------
|
||||
|
||||
:host(.button-soft) {
|
||||
--border-radius: #{globals.$ion-soft-xs};
|
||||
--border-radius: #{globals.$ion-border-radius-200};
|
||||
}
|
||||
|
||||
// Round Button
|
||||
// --------------------------------------------------
|
||||
|
||||
:host(.button-round) {
|
||||
--border-radius: #{globals.$ion-round-xs};
|
||||
--border-radius: #{globals.$ion-border-radius-full};
|
||||
}
|
||||
|
||||
// Rectangular Button
|
||||
// --------------------------------------------------
|
||||
|
||||
:host(.button-rectangular) {
|
||||
--border-radius: #{globals.$ion-rectangular-xs};
|
||||
--border-radius: #{globals.$ion-border-radius-0};
|
||||
}
|
||||
|
||||
// Button: Focus
|
||||
@@ -218,15 +211,8 @@
|
||||
background: globals.current-color(shade);
|
||||
}
|
||||
|
||||
:host(.button-outline.ion-color.ion-activated) .button-native::after,
|
||||
:host(.button-clear.ion-color.ion-activated) .button-native::after {
|
||||
background: globals.current-color(shade, $subtle: true);
|
||||
}
|
||||
|
||||
:host(.ion-activated) .button-native:has(ion-ripple-effect)::after,
|
||||
:host(.button-solid.ion-color.ion-activated) .button-native:has(ion-ripple-effect)::after,
|
||||
:host(.button-outline.ion-color.ion-activated) .button-native:has(ion-ripple-effect)::after,
|
||||
:host(.button-clear.ion-color.ion-activated) .button-native:has(ion-ripple-effect)::after {
|
||||
:host(.button-solid.ion-color.ion-activated) .button-native:has(ion-ripple-effect)::after {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
@@ -237,11 +223,6 @@
|
||||
:host(.button-solid.ion-color:hover) .button-native::after {
|
||||
background: globals.current-color(shade);
|
||||
}
|
||||
|
||||
:host(.button-outline.ion-color:hover) .button-native::after,
|
||||
:host(.button-clear.ion-color:hover) .button-native::after {
|
||||
background: globals.current-color(shade, $subtle: true);
|
||||
}
|
||||
}
|
||||
|
||||
// Button: Disabled
|
||||
|
||||
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 101 KiB After Width: | Height: | Size: 105 KiB |
|
Before Width: | Height: | Size: 136 KiB After Width: | Height: | Size: 137 KiB |
|
Before Width: | Height: | Size: 130 KiB After Width: | Height: | Size: 131 KiB |
|
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 106 KiB |
|
Before Width: | Height: | Size: 137 KiB After Width: | Height: | Size: 138 KiB |
|
Before Width: | Height: | Size: 131 KiB After Width: | Height: | Size: 133 KiB |
|
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 98 KiB |
|
Before Width: | Height: | Size: 128 KiB After Width: | Height: | Size: 130 KiB |
|
Before Width: | Height: | Size: 126 KiB After Width: | Height: | Size: 127 KiB |
|
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 100 KiB |
|
Before Width: | Height: | Size: 128 KiB After Width: | Height: | Size: 129 KiB |
|
Before Width: | Height: | Size: 126 KiB After Width: | Height: | Size: 128 KiB |
|
Before Width: | Height: | Size: 125 KiB After Width: | Height: | Size: 125 KiB |
|
Before Width: | Height: | Size: 168 KiB After Width: | Height: | Size: 164 KiB |
|
Before Width: | Height: | Size: 157 KiB After Width: | Height: | Size: 155 KiB |
|
Before Width: | Height: | Size: 148 KiB After Width: | Height: | Size: 154 KiB |
|
Before Width: | Height: | Size: 194 KiB After Width: | Height: | Size: 198 KiB |
|
Before Width: | Height: | Size: 187 KiB After Width: | Height: | Size: 190 KiB |
|
Before Width: | Height: | Size: 148 KiB After Width: | Height: | Size: 153 KiB |
|
Before Width: | Height: | Size: 194 KiB After Width: | Height: | Size: 198 KiB |
|
Before Width: | Height: | Size: 188 KiB After Width: | Height: | Size: 191 KiB |
|
Before Width: | Height: | Size: 124 KiB After Width: | Height: | Size: 130 KiB |
|
Before Width: | Height: | Size: 168 KiB After Width: | Height: | Size: 174 KiB |
|
Before Width: | Height: | Size: 179 KiB After Width: | Height: | Size: 186 KiB |
|
Before Width: | Height: | Size: 124 KiB After Width: | Height: | Size: 130 KiB |
|
Before Width: | Height: | Size: 167 KiB After Width: | Height: | Size: 173 KiB |
|
Before Width: | Height: | Size: 179 KiB After Width: | Height: | Size: 186 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.0 KiB |
@@ -56,8 +56,7 @@
|
||||
<ion-select-option value="primary">Primary</ion-select-option>
|
||||
<ion-select-option value="success">Success</ion-select-option>
|
||||
<ion-select-option value="warning">Warning</ion-select-option>
|
||||
<ion-select-option value="medium">Medium</ion-select-option>
|
||||
<ion-select-option value="danger">Danger</ion-select-option>
|
||||
<ion-select-option value="neutral">Neutral</ion-select-option>
|
||||
</ion-select>
|
||||
</p>
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// --------------------------------------------------
|
||||
|
||||
::slotted(*) .button-clear {
|
||||
--color: #{globals.$ion-text-default};
|
||||
--color: #{globals.$ion-primitives-neutral-1200};
|
||||
--background: transparent;
|
||||
--background-activated: transparent;
|
||||
--background-focused: transparent;
|
||||
|
||||
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1018 B |
|
Before Width: | Height: | Size: 968 B After Width: | Height: | Size: 1004 B |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.5 KiB |
@@ -5,7 +5,7 @@
|
||||
// --------------------------------------------------
|
||||
|
||||
:host {
|
||||
--color: #{globals.$ion-text-default};
|
||||
--color: #{globals.$ion-primitives-neutral-1200};
|
||||
|
||||
@include globals.typography(globals.$ion-heading-h5-medium);
|
||||
}
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
// --------------------------------------------------
|
||||
|
||||
:host {
|
||||
--background: #{globals.$ion-bg-surface-default};
|
||||
--background: #{globals.$ion-primitives-base-white};
|
||||
--border-width: #{globals.$ion-border-size-025};
|
||||
--border-color: #{globals.$ion-border-default};
|
||||
--border-style: #{globals.$ion-border-style-solid};
|
||||
--border-radius: #{globals.$ion-round-xl};
|
||||
--color: #{globals.$ion-text-default};
|
||||
--color: #{globals.$ion-primitives-neutral-1200};
|
||||
min-width: globals.$ion-scale-2400;
|
||||
|
||||
border: var(--border-width) var(--border-style) var(--border-color);
|
||||
|
||||
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 33 KiB |
@@ -30,7 +30,7 @@
|
||||
--checkbox-background: #{globals.$ion-bg-input-default};
|
||||
--checkbox-background-checked: #{globals.$ion-bg-primary-base-default};
|
||||
--border-color-checked: #{globals.$ion-semantics-primary-base};
|
||||
--checkmark-color: #{globals.$ion-bg-surface-default};
|
||||
--checkmark-color: #{globals.$ion-primitives-base-white};
|
||||
--transition: none;
|
||||
|
||||
z-index: 2;
|
||||
@@ -60,7 +60,7 @@
|
||||
}
|
||||
|
||||
.label-text-wrapper {
|
||||
color: globals.$ion-text-default;
|
||||
color: globals.$ion-primitives-neutral-1200;
|
||||
}
|
||||
|
||||
:host(.in-item) .label-text-wrapper {
|
||||
|
||||
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
@@ -117,13 +117,13 @@
|
||||
|
||||
:host(.chip-bold) {
|
||||
--background: #{globals.$ion-bg-neutral-bold-default};
|
||||
--color: #{globals.$ion-bg-surface-default};
|
||||
--color: #{globals.$ion-primitives-base-white};
|
||||
}
|
||||
|
||||
:host(.chip-outline.chip-bold) {
|
||||
// TODO(FW-6450): this is a made up design choice based on a
|
||||
// darker shade of the background color
|
||||
border-color: globals.$ion-text-default;
|
||||
border-color: globals.$ion-primitives-neutral-1200;
|
||||
}
|
||||
|
||||
// Chip Colors
|
||||
|
||||
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 6.0 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 39 KiB |
@@ -4,13 +4,6 @@
|
||||
// --------------------------------------------------
|
||||
|
||||
:host {
|
||||
/**
|
||||
* @prop --col-unit-size: The size of each Column unit.
|
||||
*/
|
||||
--col-unit-size: calc(
|
||||
(100% - (var(--ion-grid-columns, 12) - 1) * var(--ion-grid-gap, 0px)) / var(--ion-grid-columns, 12)
|
||||
);
|
||||
|
||||
/**
|
||||
* @prop --ion-grid-columns: The number of total Columns in the Grid
|
||||
* @prop --ion-grid-column-padding: Padding for the Column
|
||||
@@ -27,55 +20,10 @@
|
||||
|
||||
position: relative;
|
||||
|
||||
flex: 1;
|
||||
flex-basis: 0;
|
||||
flex-grow: 1;
|
||||
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
min-height: 1px; // Prevent columns from collapsing when empty
|
||||
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
:host(.ion-grid-col-auto) {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
:host([class^="ion-grid-col--"]),
|
||||
:host([class*=" ion-grid-col--"]) {
|
||||
flex: 0 0
|
||||
calc(var(--ion-grid-col-span) * var(--col-unit-size) + (var(--ion-grid-col-span) - 1) * var(--ion-grid-gap, 0px));
|
||||
|
||||
max-width: calc(
|
||||
var(--ion-grid-col-span) * var(--col-unit-size) + (var(--ion-grid-col-span) - 1) * var(--ion-grid-gap, 0px)
|
||||
);
|
||||
}
|
||||
|
||||
:host([class^="ion-grid-offset-col--"]),
|
||||
:host([class*=" ion-grid-offset-col--"]) {
|
||||
--margin-calc: calc(
|
||||
var(--col-unit-size) * var(--ion-grid-col-margin) + (var(--ion-grid-gap, 0px) * var(--ion-grid-col-margin))
|
||||
);
|
||||
|
||||
@include margin-horizontal(var(--margin-calc), 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* While the number of columns can be customized, we generate
|
||||
* a default set of classes for 12 columns. In the future, this
|
||||
* will be configurable at build time as Ionic becomes more modular.
|
||||
* For now, 12 columns is a practical default. Developers who need
|
||||
* more columns can override or extend these styles as needed.
|
||||
*/
|
||||
$grid-col-number: 12;
|
||||
|
||||
@for $i from 1 through $grid-col-number {
|
||||
:host(.ion-grid-col--#{$i}) {
|
||||
--ion-grid-col-span: #{$i};
|
||||
}
|
||||
|
||||
:host(.ion-grid-order-col--#{$i}) {
|
||||
order: #{$i};
|
||||
}
|
||||
|
||||
:host(.ion-grid-offset-col--#{$i}) {
|
||||
--ion-grid-col-margin: #{$i};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import type { ComponentInterface } from '@stencil/core';
|
||||
import { Component, Element, Host, Listen, Prop, forceUpdate, h } from '@stencil/core';
|
||||
import { printIonWarning } from '@utils/logging';
|
||||
import { Component, Host, Listen, Prop, forceUpdate, h } from '@stencil/core';
|
||||
import { matchBreakpoint } from '@utils/media';
|
||||
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
|
||||
const win = typeof (window as any) !== 'undefined' ? (window as any) : undefined;
|
||||
// eslint-disable-next-line @typescript-eslint/prefer-optional-chain
|
||||
const SUPPORTS_VARS = win && !!(win.CSS && win.CSS.supports && win.CSS.supports('--a: 0'));
|
||||
const BREAKPOINTS = ['', 'xs', 'sm', 'md', 'lg', 'xl'];
|
||||
|
||||
/**
|
||||
@@ -18,7 +19,6 @@ const BREAKPOINTS = ['', 'xs', 'sm', 'md', 'lg', 'xl'];
|
||||
shadow: true,
|
||||
})
|
||||
export class Col implements ComponentInterface {
|
||||
@Element() el!: HTMLIonColElement;
|
||||
/**
|
||||
* The amount to offset the column, in terms of how many columns it should shift to the end
|
||||
* of the total available.
|
||||
@@ -55,112 +55,71 @@ export class Col implements ComponentInterface {
|
||||
*/
|
||||
@Prop() offsetXl?: string;
|
||||
|
||||
/**
|
||||
* The order of the column, in terms of where the column should position itself in the columns renderer.
|
||||
* If no value is passed, the column order implicit value will be the order in the html structure.
|
||||
*/
|
||||
@Prop() order?: string;
|
||||
|
||||
/**
|
||||
* The order of the column for xs screens, in terms of where the column should position itself in the columns renderer.
|
||||
* If no value is passed, the column order implicit value will be the order in the html structure.
|
||||
*/
|
||||
@Prop() orderXs?: string;
|
||||
|
||||
/**
|
||||
* The order of the column for sm screens, in terms of where the column should position itself in the columns renderer.
|
||||
* If no value is passed, the column order implicit value will be the order in the html structure.
|
||||
*/
|
||||
@Prop() orderSm?: string;
|
||||
|
||||
/**
|
||||
* The order of the column for md screens, in terms of where the column should position itself in the columns renderer.
|
||||
* If no value is passed, the column order implicit value will be the order in the html structure.
|
||||
*/
|
||||
@Prop() orderMd?: string;
|
||||
|
||||
/**
|
||||
* The order of the column for lg screens, in terms of where the column should position itself in the columns renderer.
|
||||
* If no value is passed, the column order implicit value will be the order in the html structure.
|
||||
*/
|
||||
@Prop() orderLg?: string;
|
||||
|
||||
/**
|
||||
* The order of the column for xl screens, in terms of where the column should position itself in the columns renderer.
|
||||
* If no value is passed, the column order implicit value will be the order in the html structure.
|
||||
*/
|
||||
@Prop() orderXl?: string;
|
||||
|
||||
/**
|
||||
* The amount to pull the column, in terms of how many columns it should shift to the start of
|
||||
* the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
@Prop() pull?: string;
|
||||
|
||||
/**
|
||||
* The amount to pull the column for xs screens, in terms of how many columns it should shift
|
||||
* to the start of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
@Prop() pullXs?: string;
|
||||
/**
|
||||
* The amount to pull the column for sm screens, in terms of how many columns it should shift
|
||||
* to the start of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
@Prop() pullSm?: string;
|
||||
/**
|
||||
* The amount to pull the column for md screens, in terms of how many columns it should shift
|
||||
* to the start of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
@Prop() pullMd?: string;
|
||||
/**
|
||||
* The amount to pull the column for lg screens, in terms of how many columns it should shift
|
||||
* to the start of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
@Prop() pullLg?: string;
|
||||
/**
|
||||
* The amount to pull the column for xl screens, in terms of how many columns it should shift
|
||||
* to the start of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
@Prop() pullXl?: string;
|
||||
|
||||
/**
|
||||
* The amount to push the column, in terms of how many columns it should shift to the end
|
||||
* of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
@Prop() push?: string;
|
||||
|
||||
/**
|
||||
* The amount to push the column for xs screens, in terms of how many columns it should shift
|
||||
* to the end of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
@Prop() pushXs?: string;
|
||||
|
||||
/**
|
||||
* The amount to push the column for sm screens, in terms of how many columns it should shift
|
||||
* to the end of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
@Prop() pushSm?: string;
|
||||
|
||||
/**
|
||||
* The amount to push the column for md screens, in terms of how many columns it should shift
|
||||
* to the end of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
@Prop() pushMd?: string;
|
||||
|
||||
/**
|
||||
* The amount to push the column for lg screens, in terms of how many columns it should shift
|
||||
* to the end of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
@Prop() pushLg?: string;
|
||||
|
||||
/**
|
||||
* The amount to push the column for xl screens, in terms of how many columns it should shift
|
||||
* to the end of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
@Prop() pushXl?: string;
|
||||
|
||||
@@ -227,78 +186,84 @@ export class Col implements ComponentInterface {
|
||||
return matched;
|
||||
}
|
||||
|
||||
private getStyleClass(property: string, className: string, acceptsAuto = false): string | undefined {
|
||||
const colPropertyValue = this.getColumns(property);
|
||||
private calculateSize() {
|
||||
const columns = this.getColumns('size');
|
||||
|
||||
// If size wasn't set for any breakpoint
|
||||
// or if the user set the size without a value
|
||||
// it means we need to stick with the default and return
|
||||
// e.g. <ion-col size-md>
|
||||
if (!colPropertyValue || colPropertyValue === '') {
|
||||
if (!columns || columns === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (acceptsAuto && colPropertyValue === 'auto') {
|
||||
return 'ion-grid-col-auto';
|
||||
}
|
||||
// If the size is set to auto then don't calculate a size
|
||||
const colSize =
|
||||
columns === 'auto'
|
||||
? 'auto'
|
||||
: // If CSS supports variables we should use the grid columns var
|
||||
SUPPORTS_VARS
|
||||
? `calc(calc(${columns} / var(--ion-grid-columns, 12)) * 100%)`
|
||||
: // Convert the columns to a percentage by dividing by the total number
|
||||
// of columns (12) and then multiplying by 100
|
||||
(columns / 12) * 100 + '%';
|
||||
|
||||
const valueNumber = parseInt(colPropertyValue);
|
||||
return {
|
||||
flex: `0 0 ${colSize}`,
|
||||
width: `${colSize}`,
|
||||
'max-width': `${colSize}`,
|
||||
};
|
||||
}
|
||||
|
||||
if (isNaN(valueNumber)) {
|
||||
// Called by push, pull, and offset since they use the same calculations
|
||||
private calculatePosition(property: string, modifier: string) {
|
||||
const columns = this.getColumns(property);
|
||||
|
||||
if (!columns) {
|
||||
return;
|
||||
}
|
||||
|
||||
return `${className}-col--${valueNumber}`;
|
||||
// If the number of columns passed are greater than 0 and less than
|
||||
// 12 we can position the column, else default to auto
|
||||
const amount = SUPPORTS_VARS
|
||||
? // If CSS supports variables we should use the grid columns var
|
||||
`calc(calc(${columns} / var(--ion-grid-columns, 12)) * 100%)`
|
||||
: // Convert the columns to a percentage by dividing by the total number
|
||||
// of columns (12) and then multiplying by 100
|
||||
columns > 0 && columns < 12
|
||||
? (columns / 12) * 100 + '%'
|
||||
: 'auto';
|
||||
|
||||
return {
|
||||
[modifier]: amount,
|
||||
};
|
||||
}
|
||||
|
||||
private getSizeClass(): string | undefined {
|
||||
return this.getStyleClass('size', 'ion-grid', true);
|
||||
private calculateOffset(isRTL: boolean) {
|
||||
return this.calculatePosition('offset', isRTL ? 'margin-right' : 'margin-left');
|
||||
}
|
||||
|
||||
private getOrderClass(): string | undefined {
|
||||
return this.getStyleClass('order', 'ion-grid-order');
|
||||
private calculatePull(isRTL: boolean) {
|
||||
return this.calculatePosition('pull', isRTL ? 'left' : 'right');
|
||||
}
|
||||
|
||||
private getOffsetClass(): string | undefined {
|
||||
return this.getStyleClass('offset', 'ion-grid-offset');
|
||||
}
|
||||
|
||||
componentDidLoad() {
|
||||
if (
|
||||
this.pull ||
|
||||
this.pullLg ||
|
||||
this.pullMd ||
|
||||
this.pullSm ||
|
||||
this.pullXl ||
|
||||
this.pullXs ||
|
||||
this.push ||
|
||||
this.pushLg ||
|
||||
this.pushMd ||
|
||||
this.pushSm ||
|
||||
this.pushXl ||
|
||||
this.pushXs
|
||||
) {
|
||||
printIonWarning(
|
||||
'[ion-col] - The pull and push properties are deprecated and no longer work, in favor of the order and size properties.',
|
||||
this.el
|
||||
);
|
||||
}
|
||||
private calculatePush(isRTL: boolean) {
|
||||
return this.calculatePosition('push', isRTL ? 'right' : 'left');
|
||||
}
|
||||
|
||||
render() {
|
||||
const isRTL = document.dir === 'rtl';
|
||||
const theme = getIonTheme(this);
|
||||
|
||||
const colSize = this.getSizeClass();
|
||||
const colOrder = this.getOrderClass();
|
||||
const colOffset = this.getOffsetClass();
|
||||
|
||||
return (
|
||||
<Host
|
||||
class={{
|
||||
[theme]: true,
|
||||
[`${colSize}`]: colSize !== undefined,
|
||||
[`${colOrder}`]: colOrder !== undefined,
|
||||
[`${colOffset}`]: colOffset !== undefined,
|
||||
}}
|
||||
style={{
|
||||
...this.calculateOffset(isRTL),
|
||||
...this.calculatePull(isRTL),
|
||||
...this.calculatePush(isRTL),
|
||||
...this.calculateSize(),
|
||||
}}
|
||||
>
|
||||
<slot></slot>
|
||||
|
||||
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 19 KiB |
@@ -9,7 +9,7 @@
|
||||
* @prop --focus-ring-color: The color of the ring around the focused element.
|
||||
* @prop --focus-ring-width: The width of the ring around the focused element.
|
||||
*/
|
||||
--background: #{globals.$ion-bg-surface-default};
|
||||
--background: #{globals.$ion-primitives-base-white};
|
||||
--focus-ring-color: #{globals.$ion-border-focus-default};
|
||||
--focus-ring-width: #{globals.$ion-border-radius-025};
|
||||
}
|
||||
@@ -140,7 +140,7 @@
|
||||
|
||||
height: globals.$ion-scale-1200;
|
||||
|
||||
color: globals.$ion-text-default;
|
||||
color: globals.$ion-primitives-neutral-1200;
|
||||
}
|
||||
|
||||
// Disabled Day
|
||||
@@ -211,7 +211,7 @@
|
||||
height: globals.$ion-scale-800;
|
||||
|
||||
background-color: globals.$ion-primitives-neutral-100;
|
||||
color: globals.$ion-text-default;
|
||||
color: globals.$ion-primitives-neutral-1200;
|
||||
}
|
||||
|
||||
// Calendar / Footer / Action Buttons
|
||||
|
||||