@jirawatpyk/aura-react 5.30.0 → 5.32.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/README.md +20 -0
- package/dist/aura.bundle.js +1146 -872
- package/dist/cjs/index.cjs +1145 -871
- package/dist/esm/Accordion.js +1 -2
- package/dist/esm/BottomNav.js +10 -4
- package/dist/esm/Combobox.js +1 -2
- package/dist/esm/Command.js +1 -2
- package/dist/esm/Field.js +21 -2
- package/dist/esm/FilterDateRange.js +5 -3
- package/dist/esm/IconButton.js +4 -1
- package/dist/esm/PageHeader.js +27 -0
- package/dist/esm/Pagination.js +3 -1
- package/dist/esm/SegmentedControl.js +3 -1
- package/dist/esm/SideNav.js +1 -0
- package/dist/esm/Stepper.js +9 -2
- package/dist/esm/Tag.js +3 -1
- package/dist/esm/TextField.js +3 -2
- package/dist/esm/Textarea.js +3 -2
- package/dist/esm/autoTip.js +182 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/theme.js +31 -0
- package/dist/index.d.cts +54 -4
- package/dist/index.d.ts +54 -4
- package/dist/server/index.cjs +61 -5
- package/dist/server/index.d.cts +22 -0
- package/dist/server/index.d.ts +22 -0
- package/dist/server/index.js +61 -5
- package/dist/styles.css +30 -2
- package/dist/styles.layer.css +30 -2
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -344,7 +344,8 @@ export interface IconButtonProps extends React$1.ButtonHTMLAttributes<HTMLButton
|
|
|
344
344
|
icon: IconInput;
|
|
345
345
|
/** `danger` colours the icon and hover for a destructive action (Delete, Revoke). */
|
|
346
346
|
tone?: "neutral" | "danger" | undefined;
|
|
347
|
-
/** Accessible name and tooltip (required).
|
|
347
|
+
/** Accessible name and tooltip (required). Since 5.32 the tooltip is AURA's own (hover and keyboard focus), not a
|
|
348
|
+
* native `title`; pass `title` yourself to keep a native one instead. */
|
|
348
349
|
label: string;
|
|
349
350
|
/** Icon size. Default `sm` (16). */
|
|
350
351
|
size?: "sm" | "md" | undefined;
|
|
@@ -415,6 +416,13 @@ export interface TextFieldProps extends FieldProps, Omit<React$1.InputHTMLAttrib
|
|
|
415
416
|
icon?: IconInput | undefined;
|
|
416
417
|
/** Trailing unit, e.g. "THB". */
|
|
417
418
|
suffix?: React$1.ReactNode | undefined;
|
|
419
|
+
/** 5.31 (Chamber-OS addendum 41): a node between the label and the box — e.g. the phrase to type, with a copy
|
|
420
|
+
* button, on a typed confirmation. The hint and error stay below. Its box's id (`{id}-addon`) comes first in the
|
|
421
|
+
* input's `aria-describedby`, so its text is read after the label; keep any button names in it short. */
|
|
422
|
+
labelAddon?: React$1.ReactNode | undefined;
|
|
423
|
+
/** `false` keeps the addon out of `aria-describedby` — for one that isn't a description (a "Forgot password?"
|
|
424
|
+
* link), or to name only part of it: give that part an id and pass it in `aria-describedby`. Default `true`. */
|
|
425
|
+
labelAddonDescribes?: boolean | undefined;
|
|
418
426
|
/** 44px box (5.30, Chamber-OS 135): `true` below 640px or on a coarse pointer, as Button's `touchHeight`; `'always'`
|
|
419
427
|
* at every width, also with a mouse in compact density — for a form whose spec asks for 44px targets everywhere.
|
|
420
428
|
* Default: the density's input height. */
|
|
@@ -540,6 +548,13 @@ export interface CommandProps {
|
|
|
540
548
|
className?: string | undefined;
|
|
541
549
|
}
|
|
542
550
|
export interface TextareaProps extends FieldProps, Omit<React$1.TextareaHTMLAttributes<HTMLTextAreaElement>, "required"> {
|
|
551
|
+
/** 5.31 (Chamber-OS addendum 41): a node between the label and the box — e.g. the phrase to type, with a copy
|
|
552
|
+
* button, on a typed confirmation. The hint and error stay below. Its box's id (`{id}-addon`) comes first in the
|
|
553
|
+
* input's `aria-describedby`, so its text is read after the label; keep any button names in it short. */
|
|
554
|
+
labelAddon?: React$1.ReactNode | undefined;
|
|
555
|
+
/** `false` keeps the addon out of `aria-describedby` — for one that isn't a description (a "Forgot password?"
|
|
556
|
+
* link), or to name only part of it: give that part an id and pass it in `aria-describedby`. Default `true`. */
|
|
557
|
+
labelAddonDescribes?: boolean | undefined;
|
|
543
558
|
/** Accepted like the other fields' (5.30, Chamber-OS 135), so a form can pass it to every field. A Textarea is
|
|
544
559
|
* always at least 96px tall, well over the 44px target, so it changes nothing you can see. */
|
|
545
560
|
touchHeight?: TouchHeight | undefined;
|
|
@@ -814,6 +829,10 @@ export interface SideNavProps {
|
|
|
814
829
|
defaultValue?: string | undefined;
|
|
815
830
|
onChange?: ((id: string) => void) | undefined;
|
|
816
831
|
header?: React$1.ReactNode | undefined;
|
|
832
|
+
/** 5.32 (DxT Monitor request 1): a full-width 1px aura-border-default line under `header`, with the board's metrics:
|
|
833
|
+
* the header at least 72px tall with its content 20px from the top and start, the line at its foot, and 16px
|
|
834
|
+
* before the first item. Default `false`. */
|
|
835
|
+
headerDivider?: boolean | undefined;
|
|
817
836
|
footer?: React$1.ReactNode | undefined;
|
|
818
837
|
/** Default "Main". */
|
|
819
838
|
label?: string | undefined;
|
|
@@ -1200,7 +1219,9 @@ export interface AppShellProps {
|
|
|
1200
1219
|
/** A BottomNav for phones (4.19). Shown below its `hideFrom` breakpoint; the content keeps room for it, and a
|
|
1201
1220
|
* viewport ActionBar sits on top of it. With a `bottomNav` and no `nav`, there is no menu button. */
|
|
1202
1221
|
bottomNav?: React$1.ReactElement | undefined;
|
|
1203
|
-
/**
|
|
1222
|
+
/** The content padding is the page margin: 16px at the sides and 24px top and bottom on phones, 24px from 640px,
|
|
1223
|
+
* 32px from 1024px. Pages don't add their own (a PageHeader has none, 5.32). `false` (5.14): `<main>` has no
|
|
1224
|
+
* padding, for pages whose containers own the page padding and column. */
|
|
1204
1225
|
contentPadding?: boolean | undefined;
|
|
1205
1226
|
className?: string | undefined;
|
|
1206
1227
|
}
|
|
@@ -1324,7 +1345,8 @@ export interface BottomNavItem {
|
|
|
1324
1345
|
/** Read after the label when `badge` is set, e.g. "new". */
|
|
1325
1346
|
badgeLabel?: string | undefined;
|
|
1326
1347
|
/** The full name for screen readers when `label` is shortened to fit (5.7), e.g. label "Konto", ariaLabel
|
|
1327
|
-
* "Mitt konto". Include the visible label in it (WCAG 2.5.3). The count or badge is
|
|
1348
|
+
* "Mitt konto". Include the visible label in it (WCAG 2.5.3); a dev warning says when it doesn't (5.32). The count or badge is
|
|
1349
|
+
* still appended. */
|
|
1328
1350
|
ariaLabel?: string | undefined;
|
|
1329
1351
|
}
|
|
1330
1352
|
export interface BottomNavProps {
|
|
@@ -1476,7 +1498,10 @@ export interface ProgressProps {
|
|
|
1476
1498
|
className?: string | undefined;
|
|
1477
1499
|
}
|
|
1478
1500
|
export interface SkeletonProps {
|
|
1479
|
-
|
|
1501
|
+
/** 5.32 (DxT Monitor request 4): `pill` is a StatusPill's size (20px tall, 22px under `lang="th"`, 72px wide) and
|
|
1502
|
+
* `badge` a Badge's (20px, 56px wide), both fully rounded, so the row doesn't move when the real one arrives.
|
|
1503
|
+
* `width` overrides the width. */
|
|
1504
|
+
variant?: "text" | "rect" | "circle" | "pill" | "badge" | undefined;
|
|
1480
1505
|
/** text only: number of lines (the last is shorter). */
|
|
1481
1506
|
lines?: number | undefined;
|
|
1482
1507
|
width?: number | string | undefined;
|
|
@@ -1634,6 +1659,9 @@ export interface FieldComponentProps extends Omit<FieldPropsPublic, "label"> {
|
|
|
1634
1659
|
/** The control's id: the label points at it, and the hint/error ids derive from it. */
|
|
1635
1660
|
id?: string | undefined;
|
|
1636
1661
|
children?: React$1.ReactNode | undefined;
|
|
1662
|
+
/** 5.31 (Chamber-OS addendum 41): a node between the label and the control, in a `.aura-field__addon` box with the
|
|
1663
|
+
* id `{id}-addon`. TextField and Textarea add that id to the input's `aria-describedby`; a custom control should too. */
|
|
1664
|
+
labelAddon?: React$1.ReactNode | undefined;
|
|
1637
1665
|
/** Render the label as another element (e.g. `span` for a group of controls) with this id. */
|
|
1638
1666
|
labelAs?: string | undefined;
|
|
1639
1667
|
labelId?: string | undefined;
|
|
@@ -1766,6 +1794,28 @@ export interface ContainerProps extends Pick<React$1.HTMLAttributes<HTMLElement>
|
|
|
1766
1794
|
}
|
|
1767
1795
|
/** Container — centres content up to aura-container-max (1280px) with responsive side padding. */
|
|
1768
1796
|
export declare const Container: React$1.ForwardRefExoticComponent<ContainerProps & React$1.RefAttributes<HTMLElement>>;
|
|
1797
|
+
/** PageHeader (5.32, DxT Monitor request 3): the top of a page — an eyebrow, the page's heading, a meta line and the
|
|
1798
|
+
* page's actions. It has no outer padding: inside AppShell, the content padding is the page margin (16px at the sides
|
|
1799
|
+
* and 24px top and bottom on phones, 24px from 640px, 32px from 1024px). Stateless, so it is also exported from
|
|
1800
|
+
* `/server`. It renders a plain `div`: to name a region by its title, put `aria-labelledby={titleId}` on your own
|
|
1801
|
+
* `<section>`, or pass `role="region"` with it. */
|
|
1802
|
+
export interface PageHeaderProps extends Pick<React$1.HTMLAttributes<HTMLElement>, "id" | "lang" | "dir" | "role">, React$1.AriaAttributes, DataAttributes {
|
|
1803
|
+
/** Small mono line above the title — a section or breadcrumb-like context ("Monitor / Sites"). */
|
|
1804
|
+
eyebrow?: React$1.ReactNode | undefined;
|
|
1805
|
+
/** The page's heading. */
|
|
1806
|
+
title: React$1.ReactNode;
|
|
1807
|
+
/** A line under the title — counts, last update, owner. */
|
|
1808
|
+
meta?: React$1.ReactNode | undefined;
|
|
1809
|
+
/** Buttons for the page, bottom-aligned at the end; they wrap below the text on a narrow screen. */
|
|
1810
|
+
actions?: React$1.ReactNode | undefined;
|
|
1811
|
+
/** Default 1. Use 2 when the page already has an h1 (e.g. in the AppShell bar). */
|
|
1812
|
+
headingLevel?: 1 | 2 | 3 | undefined;
|
|
1813
|
+
/** The heading's id, for `aria-labelledby` on the page's region. */
|
|
1814
|
+
titleId?: string | undefined;
|
|
1815
|
+
className?: string | undefined;
|
|
1816
|
+
style?: React$1.CSSProperties | undefined;
|
|
1817
|
+
}
|
|
1818
|
+
export declare const PageHeader: React$1.ForwardRefExoticComponent<PageHeaderProps & React$1.RefAttributes<HTMLDivElement>>;
|
|
1769
1819
|
/** AppShell — side navigation + top bar + content. The nav is fixed from lg (1024px) up and a Drawer below it.
|
|
1770
1820
|
* Which one shows is decided in CSS (4.16), so the server's HTML is already right on a phone and nothing shifts on
|
|
1771
1821
|
* hydration; JavaScript only opens and closes the drawer. */
|
package/dist/index.d.ts
CHANGED
|
@@ -344,7 +344,8 @@ export interface IconButtonProps extends React$1.ButtonHTMLAttributes<HTMLButton
|
|
|
344
344
|
icon: IconInput;
|
|
345
345
|
/** `danger` colours the icon and hover for a destructive action (Delete, Revoke). */
|
|
346
346
|
tone?: "neutral" | "danger" | undefined;
|
|
347
|
-
/** Accessible name and tooltip (required).
|
|
347
|
+
/** Accessible name and tooltip (required). Since 5.32 the tooltip is AURA's own (hover and keyboard focus), not a
|
|
348
|
+
* native `title`; pass `title` yourself to keep a native one instead. */
|
|
348
349
|
label: string;
|
|
349
350
|
/** Icon size. Default `sm` (16). */
|
|
350
351
|
size?: "sm" | "md" | undefined;
|
|
@@ -415,6 +416,13 @@ export interface TextFieldProps extends FieldProps, Omit<React$1.InputHTMLAttrib
|
|
|
415
416
|
icon?: IconInput | undefined;
|
|
416
417
|
/** Trailing unit, e.g. "THB". */
|
|
417
418
|
suffix?: React$1.ReactNode | undefined;
|
|
419
|
+
/** 5.31 (Chamber-OS addendum 41): a node between the label and the box — e.g. the phrase to type, with a copy
|
|
420
|
+
* button, on a typed confirmation. The hint and error stay below. Its box's id (`{id}-addon`) comes first in the
|
|
421
|
+
* input's `aria-describedby`, so its text is read after the label; keep any button names in it short. */
|
|
422
|
+
labelAddon?: React$1.ReactNode | undefined;
|
|
423
|
+
/** `false` keeps the addon out of `aria-describedby` — for one that isn't a description (a "Forgot password?"
|
|
424
|
+
* link), or to name only part of it: give that part an id and pass it in `aria-describedby`. Default `true`. */
|
|
425
|
+
labelAddonDescribes?: boolean | undefined;
|
|
418
426
|
/** 44px box (5.30, Chamber-OS 135): `true` below 640px or on a coarse pointer, as Button's `touchHeight`; `'always'`
|
|
419
427
|
* at every width, also with a mouse in compact density — for a form whose spec asks for 44px targets everywhere.
|
|
420
428
|
* Default: the density's input height. */
|
|
@@ -540,6 +548,13 @@ export interface CommandProps {
|
|
|
540
548
|
className?: string | undefined;
|
|
541
549
|
}
|
|
542
550
|
export interface TextareaProps extends FieldProps, Omit<React$1.TextareaHTMLAttributes<HTMLTextAreaElement>, "required"> {
|
|
551
|
+
/** 5.31 (Chamber-OS addendum 41): a node between the label and the box — e.g. the phrase to type, with a copy
|
|
552
|
+
* button, on a typed confirmation. The hint and error stay below. Its box's id (`{id}-addon`) comes first in the
|
|
553
|
+
* input's `aria-describedby`, so its text is read after the label; keep any button names in it short. */
|
|
554
|
+
labelAddon?: React$1.ReactNode | undefined;
|
|
555
|
+
/** `false` keeps the addon out of `aria-describedby` — for one that isn't a description (a "Forgot password?"
|
|
556
|
+
* link), or to name only part of it: give that part an id and pass it in `aria-describedby`. Default `true`. */
|
|
557
|
+
labelAddonDescribes?: boolean | undefined;
|
|
543
558
|
/** Accepted like the other fields' (5.30, Chamber-OS 135), so a form can pass it to every field. A Textarea is
|
|
544
559
|
* always at least 96px tall, well over the 44px target, so it changes nothing you can see. */
|
|
545
560
|
touchHeight?: TouchHeight | undefined;
|
|
@@ -814,6 +829,10 @@ export interface SideNavProps {
|
|
|
814
829
|
defaultValue?: string | undefined;
|
|
815
830
|
onChange?: ((id: string) => void) | undefined;
|
|
816
831
|
header?: React$1.ReactNode | undefined;
|
|
832
|
+
/** 5.32 (DxT Monitor request 1): a full-width 1px aura-border-default line under `header`, with the board's metrics:
|
|
833
|
+
* the header at least 72px tall with its content 20px from the top and start, the line at its foot, and 16px
|
|
834
|
+
* before the first item. Default `false`. */
|
|
835
|
+
headerDivider?: boolean | undefined;
|
|
817
836
|
footer?: React$1.ReactNode | undefined;
|
|
818
837
|
/** Default "Main". */
|
|
819
838
|
label?: string | undefined;
|
|
@@ -1200,7 +1219,9 @@ export interface AppShellProps {
|
|
|
1200
1219
|
/** A BottomNav for phones (4.19). Shown below its `hideFrom` breakpoint; the content keeps room for it, and a
|
|
1201
1220
|
* viewport ActionBar sits on top of it. With a `bottomNav` and no `nav`, there is no menu button. */
|
|
1202
1221
|
bottomNav?: React$1.ReactElement | undefined;
|
|
1203
|
-
/**
|
|
1222
|
+
/** The content padding is the page margin: 16px at the sides and 24px top and bottom on phones, 24px from 640px,
|
|
1223
|
+
* 32px from 1024px. Pages don't add their own (a PageHeader has none, 5.32). `false` (5.14): `<main>` has no
|
|
1224
|
+
* padding, for pages whose containers own the page padding and column. */
|
|
1204
1225
|
contentPadding?: boolean | undefined;
|
|
1205
1226
|
className?: string | undefined;
|
|
1206
1227
|
}
|
|
@@ -1324,7 +1345,8 @@ export interface BottomNavItem {
|
|
|
1324
1345
|
/** Read after the label when `badge` is set, e.g. "new". */
|
|
1325
1346
|
badgeLabel?: string | undefined;
|
|
1326
1347
|
/** The full name for screen readers when `label` is shortened to fit (5.7), e.g. label "Konto", ariaLabel
|
|
1327
|
-
* "Mitt konto". Include the visible label in it (WCAG 2.5.3). The count or badge is
|
|
1348
|
+
* "Mitt konto". Include the visible label in it (WCAG 2.5.3); a dev warning says when it doesn't (5.32). The count or badge is
|
|
1349
|
+
* still appended. */
|
|
1328
1350
|
ariaLabel?: string | undefined;
|
|
1329
1351
|
}
|
|
1330
1352
|
export interface BottomNavProps {
|
|
@@ -1476,7 +1498,10 @@ export interface ProgressProps {
|
|
|
1476
1498
|
className?: string | undefined;
|
|
1477
1499
|
}
|
|
1478
1500
|
export interface SkeletonProps {
|
|
1479
|
-
|
|
1501
|
+
/** 5.32 (DxT Monitor request 4): `pill` is a StatusPill's size (20px tall, 22px under `lang="th"`, 72px wide) and
|
|
1502
|
+
* `badge` a Badge's (20px, 56px wide), both fully rounded, so the row doesn't move when the real one arrives.
|
|
1503
|
+
* `width` overrides the width. */
|
|
1504
|
+
variant?: "text" | "rect" | "circle" | "pill" | "badge" | undefined;
|
|
1480
1505
|
/** text only: number of lines (the last is shorter). */
|
|
1481
1506
|
lines?: number | undefined;
|
|
1482
1507
|
width?: number | string | undefined;
|
|
@@ -1634,6 +1659,9 @@ export interface FieldComponentProps extends Omit<FieldPropsPublic, "label"> {
|
|
|
1634
1659
|
/** The control's id: the label points at it, and the hint/error ids derive from it. */
|
|
1635
1660
|
id?: string | undefined;
|
|
1636
1661
|
children?: React$1.ReactNode | undefined;
|
|
1662
|
+
/** 5.31 (Chamber-OS addendum 41): a node between the label and the control, in a `.aura-field__addon` box with the
|
|
1663
|
+
* id `{id}-addon`. TextField and Textarea add that id to the input's `aria-describedby`; a custom control should too. */
|
|
1664
|
+
labelAddon?: React$1.ReactNode | undefined;
|
|
1637
1665
|
/** Render the label as another element (e.g. `span` for a group of controls) with this id. */
|
|
1638
1666
|
labelAs?: string | undefined;
|
|
1639
1667
|
labelId?: string | undefined;
|
|
@@ -1766,6 +1794,28 @@ export interface ContainerProps extends Pick<React$1.HTMLAttributes<HTMLElement>
|
|
|
1766
1794
|
}
|
|
1767
1795
|
/** Container — centres content up to aura-container-max (1280px) with responsive side padding. */
|
|
1768
1796
|
export declare const Container: React$1.ForwardRefExoticComponent<ContainerProps & React$1.RefAttributes<HTMLElement>>;
|
|
1797
|
+
/** PageHeader (5.32, DxT Monitor request 3): the top of a page — an eyebrow, the page's heading, a meta line and the
|
|
1798
|
+
* page's actions. It has no outer padding: inside AppShell, the content padding is the page margin (16px at the sides
|
|
1799
|
+
* and 24px top and bottom on phones, 24px from 640px, 32px from 1024px). Stateless, so it is also exported from
|
|
1800
|
+
* `/server`. It renders a plain `div`: to name a region by its title, put `aria-labelledby={titleId}` on your own
|
|
1801
|
+
* `<section>`, or pass `role="region"` with it. */
|
|
1802
|
+
export interface PageHeaderProps extends Pick<React$1.HTMLAttributes<HTMLElement>, "id" | "lang" | "dir" | "role">, React$1.AriaAttributes, DataAttributes {
|
|
1803
|
+
/** Small mono line above the title — a section or breadcrumb-like context ("Monitor / Sites"). */
|
|
1804
|
+
eyebrow?: React$1.ReactNode | undefined;
|
|
1805
|
+
/** The page's heading. */
|
|
1806
|
+
title: React$1.ReactNode;
|
|
1807
|
+
/** A line under the title — counts, last update, owner. */
|
|
1808
|
+
meta?: React$1.ReactNode | undefined;
|
|
1809
|
+
/** Buttons for the page, bottom-aligned at the end; they wrap below the text on a narrow screen. */
|
|
1810
|
+
actions?: React$1.ReactNode | undefined;
|
|
1811
|
+
/** Default 1. Use 2 when the page already has an h1 (e.g. in the AppShell bar). */
|
|
1812
|
+
headingLevel?: 1 | 2 | 3 | undefined;
|
|
1813
|
+
/** The heading's id, for `aria-labelledby` on the page's region. */
|
|
1814
|
+
titleId?: string | undefined;
|
|
1815
|
+
className?: string | undefined;
|
|
1816
|
+
style?: React$1.CSSProperties | undefined;
|
|
1817
|
+
}
|
|
1818
|
+
export declare const PageHeader: React$1.ForwardRefExoticComponent<PageHeaderProps & React$1.RefAttributes<HTMLDivElement>>;
|
|
1769
1819
|
/** AppShell — side navigation + top bar + content. The nav is fixed from lg (1024px) up and a Drawer below it.
|
|
1770
1820
|
* Which one shows is decided in CSS (4.16), so the server's HTML is already right on a phone and nothing shifts on
|
|
1771
1821
|
* hydration; JavaScript only opens and closes the drawer. */
|
package/dist/server/index.cjs
CHANGED
|
@@ -37,6 +37,7 @@ __export(server_exports, {
|
|
|
37
37
|
Container: () => Container,
|
|
38
38
|
EmptyState: () => ServerEmptyState,
|
|
39
39
|
Icon: () => Icon,
|
|
40
|
+
PageHeader: () => PageHeader,
|
|
40
41
|
STRINGS: () => STRINGS,
|
|
41
42
|
Stat: () => ServerStat,
|
|
42
43
|
StatusPill: () => ServerStatusPill,
|
|
@@ -606,14 +607,14 @@ var STRINGS = {
|
|
|
606
607
|
|
|
607
608
|
// src/theme.ts
|
|
608
609
|
function hexToRgb(hex) {
|
|
609
|
-
let
|
|
610
|
-
if (
|
|
611
|
-
|
|
610
|
+
let h5 = String(hex).trim().replace("#", "");
|
|
611
|
+
if (h5.length === 3)
|
|
612
|
+
h5 = h5.split("").map(function(c) {
|
|
612
613
|
return c + c;
|
|
613
614
|
}).join("");
|
|
614
|
-
if (!/^[0-9a-f]{6}$/i.test(
|
|
615
|
+
if (!/^[0-9a-f]{6}$/i.test(h5)) throw new Error('createTheme: "' + hex + '" is not a #rgb or #rrggbb colour');
|
|
615
616
|
return [0, 2, 4].map(function(i) {
|
|
616
|
-
return parseInt(
|
|
617
|
+
return parseInt(h5.slice(i, i + 2), 16) / 255;
|
|
617
618
|
});
|
|
618
619
|
}
|
|
619
620
|
function rgbToHex(rgb) {
|
|
@@ -768,6 +769,13 @@ function createTheme(opts) {
|
|
|
768
769
|
D["accent-lime"] = s[200];
|
|
769
770
|
D["mesh-to"] = s[200];
|
|
770
771
|
}
|
|
772
|
+
function onFill(bg) {
|
|
773
|
+
return contrast(ZINC[0], bg) >= contrast(INK, bg) ? ZINC[0] : INK;
|
|
774
|
+
}
|
|
775
|
+
L["control-checked-bg"] = L["accent-violet"];
|
|
776
|
+
L["control-checked-fg"] = onFill(L["control-checked-bg"]);
|
|
777
|
+
D["control-checked-bg"] = fit(b[300], darkGrounds, 3, 1);
|
|
778
|
+
D["control-checked-fg"] = onFill(D["control-checked-bg"]);
|
|
771
779
|
const shadowLight = INK, shadowDark = D["accent-violet"];
|
|
772
780
|
if (o.primary === "brand") {
|
|
773
781
|
L["button-primary-bg"] = fit(b[600], [ZINC[0]], 4.5, -1);
|
|
@@ -850,6 +858,30 @@ function createTheme(opts) {
|
|
|
850
858
|
);
|
|
851
859
|
}
|
|
852
860
|
if (s) check("light", "ink", "accent-lime (signal)", 4.5, INK, s[200]);
|
|
861
|
+
[
|
|
862
|
+
[
|
|
863
|
+
"light",
|
|
864
|
+
L,
|
|
865
|
+
[
|
|
866
|
+
["bg-surface", ZINC[0]],
|
|
867
|
+
["bg-canvas", ZINC[50]]
|
|
868
|
+
]
|
|
869
|
+
],
|
|
870
|
+
[
|
|
871
|
+
"dark",
|
|
872
|
+
D,
|
|
873
|
+
[
|
|
874
|
+
["bg-surface", ZINC[900]],
|
|
875
|
+
["bg-canvas", ZINC[950]]
|
|
876
|
+
]
|
|
877
|
+
]
|
|
878
|
+
].forEach(function(g) {
|
|
879
|
+
const t = g[0], m = g[1];
|
|
880
|
+
g[2].forEach(function(gr) {
|
|
881
|
+
check(t, "control-checked-bg", gr[0], 3, m["control-checked-bg"], gr[1]);
|
|
882
|
+
});
|
|
883
|
+
check(t, "control-checked-fg", "control-checked-bg", 4.5, m["control-checked-fg"], m["control-checked-bg"]);
|
|
884
|
+
});
|
|
853
885
|
function css(selector) {
|
|
854
886
|
if (selector !== void 0 && /[<{};@\r\n]|\/\*|\*\//.test(selector))
|
|
855
887
|
throw new Error('createTheme: "' + selector + '" is not a plain CSS selector');
|
|
@@ -1344,3 +1376,27 @@ var Container = React4.forwardRef(function Container2(props, ref) {
|
|
|
1344
1376
|
props.children
|
|
1345
1377
|
);
|
|
1346
1378
|
});
|
|
1379
|
+
|
|
1380
|
+
// src/PageHeader.tsx
|
|
1381
|
+
var React5 = __toESM(require("react"), 1);
|
|
1382
|
+
var h4 = React5.createElement;
|
|
1383
|
+
var PageHeader = React5.forwardRef(function PageHeader2(props, ref) {
|
|
1384
|
+
const attrs = {};
|
|
1385
|
+
Object.keys(props).forEach(function(k) {
|
|
1386
|
+
if (k === "id" || k === "lang" || k === "dir" || k === "role" || /^(aria|data)-/.test(k))
|
|
1387
|
+
attrs[k] = props[k];
|
|
1388
|
+
});
|
|
1389
|
+
const level = props.headingLevel || 1;
|
|
1390
|
+
return h4(
|
|
1391
|
+
"div",
|
|
1392
|
+
Object.assign(attrs, { ref, className: cx("aura-page-header", props.className), style: props.style }),
|
|
1393
|
+
h4(
|
|
1394
|
+
"div",
|
|
1395
|
+
{ className: "aura-page-header__text" },
|
|
1396
|
+
props.eyebrow != null && props.eyebrow !== false ? h4("p", { className: "aura-page-header__eyebrow" }, props.eyebrow) : null,
|
|
1397
|
+
h4("h" + level, { className: "aura-page-header__title", id: props.titleId }, props.title),
|
|
1398
|
+
props.meta != null && props.meta !== false ? h4("div", { className: "aura-page-header__meta" }, props.meta) : null
|
|
1399
|
+
),
|
|
1400
|
+
props.actions != null && props.actions !== false ? h4("div", { className: "aura-page-header__actions" }, props.actions) : null
|
|
1401
|
+
);
|
|
1402
|
+
});
|
package/dist/server/index.d.cts
CHANGED
|
@@ -404,6 +404,28 @@ export interface ContainerProps extends Pick<React$1.HTMLAttributes<HTMLElement>
|
|
|
404
404
|
}
|
|
405
405
|
/** Container — centres content up to aura-container-max (1280px) with responsive side padding. */
|
|
406
406
|
export declare const Container: React$1.ForwardRefExoticComponent<ContainerProps & React$1.RefAttributes<HTMLElement>>;
|
|
407
|
+
/** PageHeader (5.32, DxT Monitor request 3): the top of a page — an eyebrow, the page's heading, a meta line and the
|
|
408
|
+
* page's actions. It has no outer padding: inside AppShell, the content padding is the page margin (16px at the sides
|
|
409
|
+
* and 24px top and bottom on phones, 24px from 640px, 32px from 1024px). Stateless, so it is also exported from
|
|
410
|
+
* `/server`. It renders a plain `div`: to name a region by its title, put `aria-labelledby={titleId}` on your own
|
|
411
|
+
* `<section>`, or pass `role="region"` with it. */
|
|
412
|
+
export interface PageHeaderProps extends Pick<React$1.HTMLAttributes<HTMLElement>, "id" | "lang" | "dir" | "role">, React$1.AriaAttributes, DataAttributes {
|
|
413
|
+
/** Small mono line above the title — a section or breadcrumb-like context ("Monitor / Sites"). */
|
|
414
|
+
eyebrow?: React$1.ReactNode | undefined;
|
|
415
|
+
/** The page's heading. */
|
|
416
|
+
title: React$1.ReactNode;
|
|
417
|
+
/** A line under the title — counts, last update, owner. */
|
|
418
|
+
meta?: React$1.ReactNode | undefined;
|
|
419
|
+
/** Buttons for the page, bottom-aligned at the end; they wrap below the text on a narrow screen. */
|
|
420
|
+
actions?: React$1.ReactNode | undefined;
|
|
421
|
+
/** Default 1. Use 2 when the page already has an h1 (e.g. in the AppShell bar). */
|
|
422
|
+
headingLevel?: 1 | 2 | 3 | undefined;
|
|
423
|
+
/** The heading's id, for `aria-labelledby` on the page's region. */
|
|
424
|
+
titleId?: string | undefined;
|
|
425
|
+
className?: string | undefined;
|
|
426
|
+
style?: React$1.CSSProperties | undefined;
|
|
427
|
+
}
|
|
428
|
+
export declare const PageHeader: React$1.ForwardRefExoticComponent<PageHeaderProps & React$1.RefAttributes<HTMLDivElement>>;
|
|
407
429
|
|
|
408
430
|
export {
|
|
409
431
|
ServerAlert as Alert,
|
package/dist/server/index.d.ts
CHANGED
|
@@ -404,6 +404,28 @@ export interface ContainerProps extends Pick<React$1.HTMLAttributes<HTMLElement>
|
|
|
404
404
|
}
|
|
405
405
|
/** Container — centres content up to aura-container-max (1280px) with responsive side padding. */
|
|
406
406
|
export declare const Container: React$1.ForwardRefExoticComponent<ContainerProps & React$1.RefAttributes<HTMLElement>>;
|
|
407
|
+
/** PageHeader (5.32, DxT Monitor request 3): the top of a page — an eyebrow, the page's heading, a meta line and the
|
|
408
|
+
* page's actions. It has no outer padding: inside AppShell, the content padding is the page margin (16px at the sides
|
|
409
|
+
* and 24px top and bottom on phones, 24px from 640px, 32px from 1024px). Stateless, so it is also exported from
|
|
410
|
+
* `/server`. It renders a plain `div`: to name a region by its title, put `aria-labelledby={titleId}` on your own
|
|
411
|
+
* `<section>`, or pass `role="region"` with it. */
|
|
412
|
+
export interface PageHeaderProps extends Pick<React$1.HTMLAttributes<HTMLElement>, "id" | "lang" | "dir" | "role">, React$1.AriaAttributes, DataAttributes {
|
|
413
|
+
/** Small mono line above the title — a section or breadcrumb-like context ("Monitor / Sites"). */
|
|
414
|
+
eyebrow?: React$1.ReactNode | undefined;
|
|
415
|
+
/** The page's heading. */
|
|
416
|
+
title: React$1.ReactNode;
|
|
417
|
+
/** A line under the title — counts, last update, owner. */
|
|
418
|
+
meta?: React$1.ReactNode | undefined;
|
|
419
|
+
/** Buttons for the page, bottom-aligned at the end; they wrap below the text on a narrow screen. */
|
|
420
|
+
actions?: React$1.ReactNode | undefined;
|
|
421
|
+
/** Default 1. Use 2 when the page already has an h1 (e.g. in the AppShell bar). */
|
|
422
|
+
headingLevel?: 1 | 2 | 3 | undefined;
|
|
423
|
+
/** The heading's id, for `aria-labelledby` on the page's region. */
|
|
424
|
+
titleId?: string | undefined;
|
|
425
|
+
className?: string | undefined;
|
|
426
|
+
style?: React$1.CSSProperties | undefined;
|
|
427
|
+
}
|
|
428
|
+
export declare const PageHeader: React$1.ForwardRefExoticComponent<PageHeaderProps & React$1.RefAttributes<HTMLDivElement>>;
|
|
407
429
|
|
|
408
430
|
export {
|
|
409
431
|
ServerAlert as Alert,
|
package/dist/server/index.js
CHANGED
|
@@ -546,14 +546,14 @@ var STRINGS = {
|
|
|
546
546
|
|
|
547
547
|
// src/theme.ts
|
|
548
548
|
function hexToRgb(hex) {
|
|
549
|
-
let
|
|
550
|
-
if (
|
|
551
|
-
|
|
549
|
+
let h5 = String(hex).trim().replace("#", "");
|
|
550
|
+
if (h5.length === 3)
|
|
551
|
+
h5 = h5.split("").map(function(c) {
|
|
552
552
|
return c + c;
|
|
553
553
|
}).join("");
|
|
554
|
-
if (!/^[0-9a-f]{6}$/i.test(
|
|
554
|
+
if (!/^[0-9a-f]{6}$/i.test(h5)) throw new Error('createTheme: "' + hex + '" is not a #rgb or #rrggbb colour');
|
|
555
555
|
return [0, 2, 4].map(function(i) {
|
|
556
|
-
return parseInt(
|
|
556
|
+
return parseInt(h5.slice(i, i + 2), 16) / 255;
|
|
557
557
|
});
|
|
558
558
|
}
|
|
559
559
|
function rgbToHex(rgb) {
|
|
@@ -708,6 +708,13 @@ function createTheme(opts) {
|
|
|
708
708
|
D["accent-lime"] = s[200];
|
|
709
709
|
D["mesh-to"] = s[200];
|
|
710
710
|
}
|
|
711
|
+
function onFill(bg) {
|
|
712
|
+
return contrast(ZINC[0], bg) >= contrast(INK, bg) ? ZINC[0] : INK;
|
|
713
|
+
}
|
|
714
|
+
L["control-checked-bg"] = L["accent-violet"];
|
|
715
|
+
L["control-checked-fg"] = onFill(L["control-checked-bg"]);
|
|
716
|
+
D["control-checked-bg"] = fit(b[300], darkGrounds, 3, 1);
|
|
717
|
+
D["control-checked-fg"] = onFill(D["control-checked-bg"]);
|
|
711
718
|
const shadowLight = INK, shadowDark = D["accent-violet"];
|
|
712
719
|
if (o.primary === "brand") {
|
|
713
720
|
L["button-primary-bg"] = fit(b[600], [ZINC[0]], 4.5, -1);
|
|
@@ -790,6 +797,30 @@ function createTheme(opts) {
|
|
|
790
797
|
);
|
|
791
798
|
}
|
|
792
799
|
if (s) check("light", "ink", "accent-lime (signal)", 4.5, INK, s[200]);
|
|
800
|
+
[
|
|
801
|
+
[
|
|
802
|
+
"light",
|
|
803
|
+
L,
|
|
804
|
+
[
|
|
805
|
+
["bg-surface", ZINC[0]],
|
|
806
|
+
["bg-canvas", ZINC[50]]
|
|
807
|
+
]
|
|
808
|
+
],
|
|
809
|
+
[
|
|
810
|
+
"dark",
|
|
811
|
+
D,
|
|
812
|
+
[
|
|
813
|
+
["bg-surface", ZINC[900]],
|
|
814
|
+
["bg-canvas", ZINC[950]]
|
|
815
|
+
]
|
|
816
|
+
]
|
|
817
|
+
].forEach(function(g) {
|
|
818
|
+
const t = g[0], m = g[1];
|
|
819
|
+
g[2].forEach(function(gr) {
|
|
820
|
+
check(t, "control-checked-bg", gr[0], 3, m["control-checked-bg"], gr[1]);
|
|
821
|
+
});
|
|
822
|
+
check(t, "control-checked-fg", "control-checked-bg", 4.5, m["control-checked-fg"], m["control-checked-bg"]);
|
|
823
|
+
});
|
|
793
824
|
function css(selector) {
|
|
794
825
|
if (selector !== void 0 && /[<{};@\r\n]|\/\*|\*\//.test(selector))
|
|
795
826
|
throw new Error('createTheme: "' + selector + '" is not a plain CSS selector');
|
|
@@ -1284,6 +1315,30 @@ var Container = React4.forwardRef(function Container2(props, ref) {
|
|
|
1284
1315
|
props.children
|
|
1285
1316
|
);
|
|
1286
1317
|
});
|
|
1318
|
+
|
|
1319
|
+
// src/PageHeader.tsx
|
|
1320
|
+
import * as React5 from "react";
|
|
1321
|
+
var h4 = React5.createElement;
|
|
1322
|
+
var PageHeader = React5.forwardRef(function PageHeader2(props, ref) {
|
|
1323
|
+
const attrs = {};
|
|
1324
|
+
Object.keys(props).forEach(function(k) {
|
|
1325
|
+
if (k === "id" || k === "lang" || k === "dir" || k === "role" || /^(aria|data)-/.test(k))
|
|
1326
|
+
attrs[k] = props[k];
|
|
1327
|
+
});
|
|
1328
|
+
const level = props.headingLevel || 1;
|
|
1329
|
+
return h4(
|
|
1330
|
+
"div",
|
|
1331
|
+
Object.assign(attrs, { ref, className: cx("aura-page-header", props.className), style: props.style }),
|
|
1332
|
+
h4(
|
|
1333
|
+
"div",
|
|
1334
|
+
{ className: "aura-page-header__text" },
|
|
1335
|
+
props.eyebrow != null && props.eyebrow !== false ? h4("p", { className: "aura-page-header__eyebrow" }, props.eyebrow) : null,
|
|
1336
|
+
h4("h" + level, { className: "aura-page-header__title", id: props.titleId }, props.title),
|
|
1337
|
+
props.meta != null && props.meta !== false ? h4("div", { className: "aura-page-header__meta" }, props.meta) : null
|
|
1338
|
+
),
|
|
1339
|
+
props.actions != null && props.actions !== false ? h4("div", { className: "aura-page-header__actions" }, props.actions) : null
|
|
1340
|
+
);
|
|
1341
|
+
});
|
|
1287
1342
|
export {
|
|
1288
1343
|
ServerAlert as Alert,
|
|
1289
1344
|
ServerAvatar as Avatar,
|
|
@@ -1292,6 +1347,7 @@ export {
|
|
|
1292
1347
|
Container,
|
|
1293
1348
|
ServerEmptyState as EmptyState,
|
|
1294
1349
|
Icon,
|
|
1350
|
+
PageHeader,
|
|
1295
1351
|
STRINGS,
|
|
1296
1352
|
ServerStat as Stat,
|
|
1297
1353
|
ServerStatusPill as StatusPill,
|
package/dist/styles.css
CHANGED
|
@@ -356,6 +356,9 @@ a.aura-icon-btn { text-decoration: none; }
|
|
|
356
356
|
background: var(--aura-bg-skeleton); animation: aura-pulse var(--aura-duration-pulse) var(--aura-ease) infinite;
|
|
357
357
|
}
|
|
358
358
|
.aura-skel--pill { width: 72px; height: 20px; }
|
|
359
|
+
.aura-skel--badge { width: 56px; height: 20px; } /* 5.32: a Badge is 20px in every language */
|
|
360
|
+
/* 5.32: they stand in for inline pills, so they sit in a line of text like them. */
|
|
361
|
+
.aura-skel--pill, .aura-skel--badge { display: inline-block; vertical-align: middle; }
|
|
359
362
|
.aura-skel--box { width: var(--aura-icon-sm); height: var(--aura-icon-sm); border-radius: var(--aura-radius-xs); }
|
|
360
363
|
@media (prefers-reduced-motion: reduce) { .aura-skel { animation: none; } }
|
|
361
364
|
/* 5.29 (Chamber-OS 134): a DataTable skeleton row stands in for the real one — text lines (skeletonLines) on the 20px
|
|
@@ -474,6 +477,8 @@ a.aura-icon-btn { text-decoration: none; }
|
|
|
474
477
|
.aura-field__hint, .aura-field__error { display: flex; align-items: flex-start; gap: var(--aura-space-1); margin: 0; font-size: 12px; line-height: 1.5; color: var(--aura-fg-secondary); }
|
|
475
478
|
.aura-field__error { color: var(--aura-fg-danger); }
|
|
476
479
|
.aura-field__error .aura-icon { margin-top: 2px; }
|
|
480
|
+
/* 5.31 (Chamber-OS addendum 41): TextField/Textarea `labelAddon`, between the label and the box, in the field's gap. */
|
|
481
|
+
.aura-field__addon { min-width: 0; font-size: 13px; line-height: 1.5; color: var(--aura-fg-primary); }
|
|
477
482
|
.aura-field.is-disabled .aura-field__label { color: var(--aura-fg-secondary); }
|
|
478
483
|
|
|
479
484
|
.aura-input {
|
|
@@ -654,6 +659,8 @@ a.aura-icon-btn { text-decoration: none; }
|
|
|
654
659
|
}
|
|
655
660
|
/* The Tooltip component's own tips can be hovered (WCAG 1.4.13, 5.1.1); rail labels and cell tips stay click-through. */
|
|
656
661
|
.aura-tooltip--hoverable { pointer-events: auto; }
|
|
662
|
+
/* 5.32: the shared tip for icon buttons, Pagination arrows, icon-only segments and cut Tags (was a native title). */
|
|
663
|
+
.aura-tooltip--auto:lang(th) { line-height: 1.6; }
|
|
657
664
|
@keyframes aura-fade-in { from { opacity: 0; } }
|
|
658
665
|
|
|
659
666
|
/* ---------- Dialog ---------- */
|
|
@@ -760,6 +767,10 @@ a.aura-tab { text-decoration: none; }
|
|
|
760
767
|
}
|
|
761
768
|
.aura-nav__header { padding: var(--aura-space-5) var(--aura-space-4) var(--aura-space-4); padding-inline-end: var(--aura-space-2); } /* 5.16 (Chamber-OS 96): 8px at the end, so a brand, its dot and a badge share one row at 240px */
|
|
762
769
|
.aura-nav__scroll { flex: 1; overflow-y: auto; padding: 0 var(--aura-space-3); }
|
|
770
|
+
/* 5.32 (DxT Monitor request 1): headerDivider — the board's header: 72px, content 20px from the top and start, a
|
|
771
|
+
* full-width line at its foot, 16px before the first item. The collapsed rail keeps its own 8px sides (below). */
|
|
772
|
+
.aura-nav--header-divider > .aura-nav__header { box-sizing: border-box; min-height: 72px; padding-top: var(--aura-space-5); padding-bottom: var(--aura-space-3); padding-inline-start: var(--aura-space-5); border-bottom: 1px solid var(--aura-border-default); }
|
|
773
|
+
.aura-nav--header-divider > .aura-nav__header + .aura-nav__scroll { padding-top: var(--aura-space-4); }
|
|
763
774
|
/* No header: keep the first item off the top edge (5.0.2). */
|
|
764
775
|
.aura-nav > .aura-nav__scroll:first-child { padding-top: var(--aura-space-3); }
|
|
765
776
|
.aura-nav--borderless { border-right: 0; }
|
|
@@ -985,7 +996,7 @@ a.aura-tab { text-decoration: none; }
|
|
|
985
996
|
.aura-drawer--lg { max-width: var(--aura-drawer-lg); }
|
|
986
997
|
.aura-drawer--nav { max-width: var(--aura-sidenav-width); }
|
|
987
998
|
.aura-drawer__head { display: flex; align-items: center; gap: var(--aura-space-3); padding: var(--aura-space-4) var(--aura-space-4) var(--aura-space-2) var(--aura-space-6); }
|
|
988
|
-
.aura-drawer--nav .aura-drawer__head { position: absolute; top: var(--aura-space-2);
|
|
999
|
+
.aura-drawer--nav .aura-drawer__head { position: absolute; top: var(--aura-space-2); inset-inline-end: var(--aura-space-2); padding: 0; z-index: 1; } /* 5.32: inline-end, so RTL puts it on the left with the header's room */
|
|
989
1000
|
.aura-drawer__title { flex: 1; margin: 0; font-size: 16px; line-height: 1.5; font-weight: 600; }
|
|
990
1001
|
.aura-drawer__desc { margin: 0; padding: 0 var(--aura-space-6); font-size: 14px; line-height: 1.7; color: var(--aura-fg-secondary); }
|
|
991
1002
|
.aura-drawer__body {
|
|
@@ -995,6 +1006,8 @@ a.aura-tab { text-decoration: none; }
|
|
|
995
1006
|
}
|
|
996
1007
|
.aura-drawer--nav .aura-drawer__body { padding: 0; }
|
|
997
1008
|
.aura-drawer--nav .aura-nav { width: 100%; border-right: 0; }
|
|
1009
|
+
/* 5.32: the phone drawer's close button (32px, 8px in) sits over the header's end: keep the brand clear of it. */
|
|
1010
|
+
.aura-drawer--nav .aura-nav__header { padding-inline-end: 48px; }
|
|
998
1011
|
.aura-drawer__foot { display: flex; justify-content: flex-end; flex-wrap: wrap; gap: var(--aura-space-3); padding: var(--aura-space-4) var(--aura-space-6); border-top: 1px solid var(--aura-border-default); }
|
|
999
1012
|
@media (prefers-reduced-motion: reduce) { .aura-drawer { animation: none; } }
|
|
1000
1013
|
|
|
@@ -1072,6 +1085,21 @@ a.aura-tab { text-decoration: none; }
|
|
|
1072
1085
|
/* The shell already pads its content: a Container directly inside only caps the width. */
|
|
1073
1086
|
.aura-shell__content:not(.is-flush) > .aura-container { padding-left: 0; padding-right: 0; }
|
|
1074
1087
|
|
|
1088
|
+
/* ---------- PageHeader (5.32, DxT Monitor request 3) ----------
|
|
1089
|
+
* No outer padding: AppShell's content padding is the page margin. Eyebrow mono 12/1.7, h1 display 36/1.15,
|
|
1090
|
+
* meta 13/1.5, 4px between them; actions at the end, on the text's last line, 24px away; below 640px the title is
|
|
1091
|
+
* 28px and the actions wrap under the text. */
|
|
1092
|
+
.aura-page-header { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: var(--aura-space-4) var(--aura-space-6); min-width: 0; font-family: var(--font-sans); }
|
|
1093
|
+
.aura-page-header__text { display: flex; flex-direction: column; gap: var(--aura-space-1); flex: 1 1 320px; min-width: 0; }
|
|
1094
|
+
.aura-page-header__eyebrow { margin: 0; font-family: var(--font-mono); font-size: 12px; line-height: 1.7; color: var(--aura-fg-secondary); overflow-wrap: anywhere; }
|
|
1095
|
+
.aura-page-header__title { margin: 0; font-family: var(--font-display); font-size: 28px; line-height: 1.15; font-weight: 600; letter-spacing: -0.01em; color: var(--aura-fg-primary); overflow-wrap: anywhere; }
|
|
1096
|
+
.aura-page-header__meta { min-width: 0; font-size: 13px; line-height: 1.5; color: var(--aura-fg-secondary); overflow-wrap: anywhere; }
|
|
1097
|
+
.aura-page-header__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--aura-space-2); }
|
|
1098
|
+
@media (min-width: 640px) { .aura-page-header__title { font-size: 36px; } }
|
|
1099
|
+
/* Thai marks need the room a 1.15 line takes away. */
|
|
1100
|
+
.aura-page-header__title:lang(th) { line-height: 1.4; letter-spacing: 0; }
|
|
1101
|
+
.aura-page-header__meta:lang(th) { line-height: 1.6; }
|
|
1102
|
+
|
|
1075
1103
|
/* Totals row (4.19): under the body, a strong top edge; sticky at the bottom of a `height` table with stickyFooter. */
|
|
1076
1104
|
/* 5.30: a 2px hairline-colour rule over the totals (border-strong was a glaring white line in dark); a pinned totals row
|
|
1077
1105
|
* casts a soft shadow over the rows scrolling under it. */
|
|
@@ -2077,7 +2105,7 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
|
|
|
2077
2105
|
/* 5.30 (audit D): field labels, hints and errors and choice descriptions get Thai line room; a stacked card's field
|
|
2078
2106
|
* labels are 12px in the sans face (the mono face has no Thai), and a stacked DataTable card's values sit on a set
|
|
2079
2107
|
* 1.6 line, so a loading card (its bars follow 1lh) is as tall as one with Thai text. */
|
|
2080
|
-
.aura-field__label:lang(th), .aura-field__hint:lang(th), .aura-field__error:lang(th) { line-height: 1.6; }
|
|
2108
|
+
.aura-field__label:lang(th), .aura-field__hint:lang(th), .aura-field__error:lang(th), .aura-field__addon:lang(th) { line-height: 1.6; }
|
|
2081
2109
|
.aura-choice__desc:lang(th), .aura-check__desc:lang(th) { font-size: 13px; line-height: 1.6; }
|
|
2082
2110
|
.aura-tbl__row > .aura-tbl__td[data-label]:lang(th)::before, .aura-table__td[data-label]:lang(th)::before { font-family: var(--font-sans); font-size: 12px; line-height: 18px; }
|
|
2083
2111
|
.aura-table--stacked .aura-table__td[data-label]:lang(th) { line-height: 1.6; }
|