twico-ui 1.48.0 → 1.49.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/index.cjs +41 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +36 -11
- package/dist/index.d.ts +36 -11
- package/dist/index.mjs +41 -0
- package/dist/index.mjs.map +1 -1
- package/llms.txt +2 -2
- package/package.json +1 -1
- package/styles/twico-ui.css +28 -10
package/dist/index.d.cts
CHANGED
|
@@ -258,7 +258,11 @@ declare function Accordion(props: AccordionProps): React.JSX.Element;
|
|
|
258
258
|
/** The canonical six-value color/intent scale used by status & control components. */
|
|
259
259
|
type Tone = "primary" | "success" | "warning" | "danger" | "info" | "neutral";
|
|
260
260
|
|
|
261
|
-
/**
|
|
261
|
+
/**
|
|
262
|
+
* The two intents most actions want. Button and IconButton accepted ONLY these until #504; they now
|
|
263
|
+
* take the full {@link Tone} scale, so this is a convenience alias for the common pair rather than a
|
|
264
|
+
* ceiling. Still exported, still accurate for anything that genuinely is brand-or-destructive.
|
|
265
|
+
*/
|
|
262
266
|
type ActionTone = "primary" | "danger";
|
|
263
267
|
|
|
264
268
|
/** Text roles, the full color scale, and `"inherit"` (adopt the parent color) — Text. */
|
|
@@ -557,8 +561,20 @@ declare function Breadcrumb(props: BreadcrumbProps): React.JSX.Element;
|
|
|
557
561
|
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
558
562
|
/** Fill style. @default "solid" */
|
|
559
563
|
variant?: "solid" | "soft" | "outline" | "ghost";
|
|
560
|
-
/**
|
|
561
|
-
|
|
564
|
+
/**
|
|
565
|
+
* Color/intent, orthogonal to `variant`. @default "primary"
|
|
566
|
+
*
|
|
567
|
+
* #504: the full {@link Tone} scale, widened from `ActionTone` (`primary | danger`). A standalone
|
|
568
|
+
* affirmative action — a row-level confirm sitting beside a `danger` sibling, reading as
|
|
569
|
+
* "yes / no" — could not be green, so the colour carrying that distinction came out the same blue
|
|
570
|
+
* as every neutral action on the page. `ActionTone` is still exported and still describes the two
|
|
571
|
+
* intents most actions want; it is no longer the ceiling.
|
|
572
|
+
*
|
|
573
|
+
* `neutral` follows Badge's mapping rather than an accent ramp of its own: `--color-text` on
|
|
574
|
+
* `--color-surface` for `solid`, `--color-surface-sunken` for `soft`. Note `variant="ghost"` and
|
|
575
|
+
* `variant="outline"` already express a quiet action, so reach for those first.
|
|
576
|
+
*/
|
|
577
|
+
tone?: Tone;
|
|
562
578
|
/** Control size; "xs" (~26px) is smaller than "sm". @default "md" */
|
|
563
579
|
size?: "xs" | "sm" | "md" | "lg";
|
|
564
580
|
/** Icon node rendered before the label. */
|
|
@@ -576,9 +592,10 @@ interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
|
576
592
|
/** #405: toggle "on" state — sets `aria-pressed` and shows a soft fill + border in the current `tone`
|
|
577
593
|
* (works with any `variant`). Omit for a plain (non-toggle) button. @default undefined */
|
|
578
594
|
pressed?: boolean;
|
|
579
|
-
/** #411: tone of the pressed ("on") fill
|
|
580
|
-
*
|
|
581
|
-
*
|
|
595
|
+
/** #411: tone of the pressed ("on") fill, so a toggle can carry a different selected-state meaning
|
|
596
|
+
* from its unpressed look. Both are the full `Tone` scale since #504 — before that `tone` was
|
|
597
|
+
* `ActionTone` and this was the only way to reach the other four. Defaults to `tone`.
|
|
598
|
+
* @default undefined */
|
|
582
599
|
pressedTone?: Tone;
|
|
583
600
|
/** Render as a different element (e.g. "a"). @default "button" */
|
|
584
601
|
as?: "button" | "a";
|
|
@@ -3939,9 +3956,16 @@ interface IconButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>
|
|
|
3939
3956
|
icon?: React.ReactNode;
|
|
3940
3957
|
/** Fill style (same axes as Button). @default "ghost" */
|
|
3941
3958
|
variant?: "solid" | "soft" | "outline" | "ghost";
|
|
3942
|
-
/**
|
|
3943
|
-
*
|
|
3944
|
-
|
|
3959
|
+
/**
|
|
3960
|
+
* Color/intent, orthogonal to `variant` (mirrors Button). A destructive icon button is
|
|
3961
|
+
* `tone="danger"` with any variant. @default "primary"
|
|
3962
|
+
*
|
|
3963
|
+
* #504: the full {@link Tone} scale, widened from `ActionTone` (`primary | danger`), so an
|
|
3964
|
+
* affirmative icon action can be green beside a destructive one. `ActionTone` is still exported
|
|
3965
|
+
* and still names the two intents most actions want; it is no longer the ceiling. `neutral`
|
|
3966
|
+
* follows Badge's mapping rather than an accent ramp of its own.
|
|
3967
|
+
*/
|
|
3968
|
+
tone?: Tone;
|
|
3945
3969
|
/** Control size; "xs" (~26px) is smaller than "sm". @default "md" */
|
|
3946
3970
|
size?: "xs" | "sm" | "md" | "lg";
|
|
3947
3971
|
/** Fully rounded (circular). @default false */
|
|
@@ -3953,8 +3977,9 @@ interface IconButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>
|
|
|
3953
3977
|
/** #405: toggle "on" state — sets `aria-pressed` and shows a soft fill + border in the current `tone`
|
|
3954
3978
|
* (works with any `variant`), e.g. a pin/unpin or bold/italic icon toggle. @default undefined */
|
|
3955
3979
|
pressed?: boolean;
|
|
3956
|
-
/** #411: tone of the pressed ("on") fill
|
|
3957
|
-
*
|
|
3980
|
+
/** #411: tone of the pressed ("on") fill, so a toggle can carry a different selected-state meaning
|
|
3981
|
+
* from its unpressed look. Both are the full `Tone` scale since #504. Defaults to `tone`.
|
|
3982
|
+
* @default undefined */
|
|
3958
3983
|
pressedTone?: Tone;
|
|
3959
3984
|
/** #342: render as a different element — use `"a"` for an icon **link** (GitHub icon, external nav, …) so
|
|
3960
3985
|
* navigation is a real link, not a button. @default "button" */
|
package/dist/index.d.ts
CHANGED
|
@@ -258,7 +258,11 @@ declare function Accordion(props: AccordionProps): React.JSX.Element;
|
|
|
258
258
|
/** The canonical six-value color/intent scale used by status & control components. */
|
|
259
259
|
type Tone = "primary" | "success" | "warning" | "danger" | "info" | "neutral";
|
|
260
260
|
|
|
261
|
-
/**
|
|
261
|
+
/**
|
|
262
|
+
* The two intents most actions want. Button and IconButton accepted ONLY these until #504; they now
|
|
263
|
+
* take the full {@link Tone} scale, so this is a convenience alias for the common pair rather than a
|
|
264
|
+
* ceiling. Still exported, still accurate for anything that genuinely is brand-or-destructive.
|
|
265
|
+
*/
|
|
262
266
|
type ActionTone = "primary" | "danger";
|
|
263
267
|
|
|
264
268
|
/** Text roles, the full color scale, and `"inherit"` (adopt the parent color) — Text. */
|
|
@@ -557,8 +561,20 @@ declare function Breadcrumb(props: BreadcrumbProps): React.JSX.Element;
|
|
|
557
561
|
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
558
562
|
/** Fill style. @default "solid" */
|
|
559
563
|
variant?: "solid" | "soft" | "outline" | "ghost";
|
|
560
|
-
/**
|
|
561
|
-
|
|
564
|
+
/**
|
|
565
|
+
* Color/intent, orthogonal to `variant`. @default "primary"
|
|
566
|
+
*
|
|
567
|
+
* #504: the full {@link Tone} scale, widened from `ActionTone` (`primary | danger`). A standalone
|
|
568
|
+
* affirmative action — a row-level confirm sitting beside a `danger` sibling, reading as
|
|
569
|
+
* "yes / no" — could not be green, so the colour carrying that distinction came out the same blue
|
|
570
|
+
* as every neutral action on the page. `ActionTone` is still exported and still describes the two
|
|
571
|
+
* intents most actions want; it is no longer the ceiling.
|
|
572
|
+
*
|
|
573
|
+
* `neutral` follows Badge's mapping rather than an accent ramp of its own: `--color-text` on
|
|
574
|
+
* `--color-surface` for `solid`, `--color-surface-sunken` for `soft`. Note `variant="ghost"` and
|
|
575
|
+
* `variant="outline"` already express a quiet action, so reach for those first.
|
|
576
|
+
*/
|
|
577
|
+
tone?: Tone;
|
|
562
578
|
/** Control size; "xs" (~26px) is smaller than "sm". @default "md" */
|
|
563
579
|
size?: "xs" | "sm" | "md" | "lg";
|
|
564
580
|
/** Icon node rendered before the label. */
|
|
@@ -576,9 +592,10 @@ interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
|
576
592
|
/** #405: toggle "on" state — sets `aria-pressed` and shows a soft fill + border in the current `tone`
|
|
577
593
|
* (works with any `variant`). Omit for a plain (non-toggle) button. @default undefined */
|
|
578
594
|
pressed?: boolean;
|
|
579
|
-
/** #411: tone of the pressed ("on") fill
|
|
580
|
-
*
|
|
581
|
-
*
|
|
595
|
+
/** #411: tone of the pressed ("on") fill, so a toggle can carry a different selected-state meaning
|
|
596
|
+
* from its unpressed look. Both are the full `Tone` scale since #504 — before that `tone` was
|
|
597
|
+
* `ActionTone` and this was the only way to reach the other four. Defaults to `tone`.
|
|
598
|
+
* @default undefined */
|
|
582
599
|
pressedTone?: Tone;
|
|
583
600
|
/** Render as a different element (e.g. "a"). @default "button" */
|
|
584
601
|
as?: "button" | "a";
|
|
@@ -3939,9 +3956,16 @@ interface IconButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>
|
|
|
3939
3956
|
icon?: React.ReactNode;
|
|
3940
3957
|
/** Fill style (same axes as Button). @default "ghost" */
|
|
3941
3958
|
variant?: "solid" | "soft" | "outline" | "ghost";
|
|
3942
|
-
/**
|
|
3943
|
-
*
|
|
3944
|
-
|
|
3959
|
+
/**
|
|
3960
|
+
* Color/intent, orthogonal to `variant` (mirrors Button). A destructive icon button is
|
|
3961
|
+
* `tone="danger"` with any variant. @default "primary"
|
|
3962
|
+
*
|
|
3963
|
+
* #504: the full {@link Tone} scale, widened from `ActionTone` (`primary | danger`), so an
|
|
3964
|
+
* affirmative icon action can be green beside a destructive one. `ActionTone` is still exported
|
|
3965
|
+
* and still names the two intents most actions want; it is no longer the ceiling. `neutral`
|
|
3966
|
+
* follows Badge's mapping rather than an accent ramp of its own.
|
|
3967
|
+
*/
|
|
3968
|
+
tone?: Tone;
|
|
3945
3969
|
/** Control size; "xs" (~26px) is smaller than "sm". @default "md" */
|
|
3946
3970
|
size?: "xs" | "sm" | "md" | "lg";
|
|
3947
3971
|
/** Fully rounded (circular). @default false */
|
|
@@ -3953,8 +3977,9 @@ interface IconButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>
|
|
|
3953
3977
|
/** #405: toggle "on" state — sets `aria-pressed` and shows a soft fill + border in the current `tone`
|
|
3954
3978
|
* (works with any `variant`), e.g. a pin/unpin or bold/italic icon toggle. @default undefined */
|
|
3955
3979
|
pressed?: boolean;
|
|
3956
|
-
/** #411: tone of the pressed ("on") fill
|
|
3957
|
-
*
|
|
3980
|
+
/** #411: tone of the pressed ("on") fill, so a toggle can carry a different selected-state meaning
|
|
3981
|
+
* from its unpressed look. Both are the full `Tone` scale since #504. Defaults to `tone`.
|
|
3982
|
+
* @default undefined */
|
|
3958
3983
|
pressedTone?: Tone;
|
|
3959
3984
|
/** #342: render as a different element — use `"a"` for an icon **link** (GitHub icon, external nav, …) so
|
|
3960
3985
|
* navigation is a real link, not a button. @default "button" */
|
package/dist/index.mjs
CHANGED
|
@@ -434,6 +434,22 @@ var ICONBTN_CSS = `
|
|
|
434
434
|
--_accent-fg: var(--color-primary-fg); --_accent-subtle: var(--color-primary-subtle); --_accent-subtle-fg: var(--color-primary-subtle-fg); }
|
|
435
435
|
.twc-iconbtn[data-tone="danger"] { --_accent: var(--color-danger); --_accent-hover: var(--color-danger-hover);
|
|
436
436
|
--_accent-fg: var(--color-danger-fg); --_accent-subtle: var(--color-danger-subtle); --_accent-subtle-fg: var(--color-danger-subtle-fg); }
|
|
437
|
+
/* #504: the full Tone scale, not just primary|danger. A standalone affirmative action - a row-level
|
|
438
|
+
confirm sitting next to a danger sibling, reading as "yes / no" - could not be green, so the colour
|
|
439
|
+
that carried the distinction came out the same blue as every neutral action on the page.
|
|
440
|
+
success/warning/info now have real -hover/-active tokens (added in tokens/colors.css on the same
|
|
441
|
+
step rule as primary and danger: light goes darker, dark goes lighter), so hover always moves AWAY
|
|
442
|
+
from the ink and contrast only improves. neutral has no accent tokens anywhere and is mapped the way
|
|
443
|
+
Badge already maps it - --color-text on --color-surface solid, --color-surface-sunken soft - with its
|
|
444
|
+
hover mixed from currentColor, since there is no --color-text-hover to point at. */
|
|
445
|
+
.twc-iconbtn[data-tone="success"] { --_accent: var(--color-success); --_accent-hover: var(--color-success-hover);
|
|
446
|
+
--_accent-fg: var(--color-success-fg); --_accent-subtle: var(--color-success-subtle); --_accent-subtle-fg: var(--color-success-subtle-fg); }
|
|
447
|
+
.twc-iconbtn[data-tone="warning"] { --_accent: var(--color-warning); --_accent-hover: var(--color-warning-hover);
|
|
448
|
+
--_accent-fg: var(--color-warning-fg); --_accent-subtle: var(--color-warning-subtle); --_accent-subtle-fg: var(--color-warning-subtle-fg); }
|
|
449
|
+
.twc-iconbtn[data-tone="info"] { --_accent: var(--color-info); --_accent-hover: var(--color-info-hover);
|
|
450
|
+
--_accent-fg: var(--color-info-fg); --_accent-subtle: var(--color-info-subtle); --_accent-subtle-fg: var(--color-info-subtle-fg); }
|
|
451
|
+
.twc-iconbtn[data-tone="neutral"] { --_accent: var(--color-text); --_accent-hover: color-mix(in srgb, var(--color-text) 88%, var(--color-surface));
|
|
452
|
+
--_accent-fg: var(--color-surface); --_accent-subtle: var(--color-surface-sunken); --_accent-subtle-fg: var(--color-text-muted); }
|
|
437
453
|
.twc-iconbtn[data-variant="solid"] { background: var(--_accent); color: var(--_accent-fg); }
|
|
438
454
|
.twc-iconbtn[data-variant="solid"]:hover:not(:disabled) { background: var(--_accent-hover); box-shadow: var(--shadow-brand); }
|
|
439
455
|
.twc-iconbtn[data-variant="solid"]:active:not(:disabled) { filter: brightness(0.92); }
|
|
@@ -1811,6 +1827,31 @@ var CSS2 = `
|
|
|
1811
1827
|
--_accent: var(--color-danger); --_accent-hover: var(--color-danger-hover); --_accent-active: var(--color-danger-hover);
|
|
1812
1828
|
--_accent-fg: var(--color-danger-fg); --_accent-subtle: var(--color-danger-subtle); --_accent-subtle-fg: var(--color-danger-subtle-fg);
|
|
1813
1829
|
}
|
|
1830
|
+
/* #504: the full Tone scale, not just primary|danger. A standalone affirmative action - a row-level
|
|
1831
|
+
confirm sitting next to a danger sibling, reading as "yes / no" - could not be green, so the colour
|
|
1832
|
+
that carried the distinction came out the same blue as every neutral action on the page.
|
|
1833
|
+
success/warning/info now have real -hover/-active tokens (added in tokens/colors.css on the same
|
|
1834
|
+
step rule as primary and danger: light goes darker, dark goes lighter), so hover always moves AWAY
|
|
1835
|
+
from the ink and contrast only improves. neutral has no accent tokens anywhere and is mapped the way
|
|
1836
|
+
Badge already maps it - --color-text on --color-surface solid, --color-surface-sunken soft - with its
|
|
1837
|
+
hover mixed from currentColor, since there is no --color-text-hover to point at. */
|
|
1838
|
+
.twc-btn[data-tone="success"] {
|
|
1839
|
+
--_accent: var(--color-success); --_accent-hover: var(--color-success-hover); --_accent-active: var(--color-success-active);
|
|
1840
|
+
--_accent-fg: var(--color-success-fg); --_accent-subtle: var(--color-success-subtle); --_accent-subtle-fg: var(--color-success-subtle-fg);
|
|
1841
|
+
}
|
|
1842
|
+
.twc-btn[data-tone="warning"] {
|
|
1843
|
+
--_accent: var(--color-warning); --_accent-hover: var(--color-warning-hover); --_accent-active: var(--color-warning-active);
|
|
1844
|
+
--_accent-fg: var(--color-warning-fg); --_accent-subtle: var(--color-warning-subtle); --_accent-subtle-fg: var(--color-warning-subtle-fg);
|
|
1845
|
+
}
|
|
1846
|
+
.twc-btn[data-tone="info"] {
|
|
1847
|
+
--_accent: var(--color-info); --_accent-hover: var(--color-info-hover); --_accent-active: var(--color-info-active);
|
|
1848
|
+
--_accent-fg: var(--color-info-fg); --_accent-subtle: var(--color-info-subtle); --_accent-subtle-fg: var(--color-info-subtle-fg);
|
|
1849
|
+
}
|
|
1850
|
+
.twc-btn[data-tone="neutral"] {
|
|
1851
|
+
--_accent: var(--color-text); --_accent-hover: color-mix(in srgb, var(--color-text) 88%, var(--color-surface));
|
|
1852
|
+
--_accent-active: color-mix(in srgb, var(--color-text) 78%, var(--color-surface));
|
|
1853
|
+
--_accent-fg: var(--color-surface); --_accent-subtle: var(--color-surface-sunken); --_accent-subtle-fg: var(--color-text-muted);
|
|
1854
|
+
}
|
|
1814
1855
|
/* solid */
|
|
1815
1856
|
.twc-btn[data-variant="solid"] { background: var(--_accent); color: var(--_accent-fg); }
|
|
1816
1857
|
.twc-btn[data-variant="solid"]:hover:not(:disabled) { background: var(--_accent-hover); box-shadow: var(--shadow-brand); }
|