@antadesign/anta 0.1.1-dev.5 → 0.1.1-dev.6

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 CHANGED
@@ -49,6 +49,19 @@ If you need a different order, declare it in your *own* CSS file that loads **be
49
49
 
50
50
  CSS custom properties (the `:root { --… }` declarations in `tokens.css`) stay unlayered so they take effect everywhere unconditionally.
51
51
 
52
+ > **Gotcha: unlayered hard resets defeat Anta's element rules.**
53
+ >
54
+ > A snippet like this in your global CSS — common copy-paste from older reset guides — silently overrides every element rule Anta ships:
55
+ >
56
+ > ```css
57
+ > *, *::before, *::after { box-sizing: border-box; }
58
+ > * { margin: 0; }
59
+ > ```
60
+ >
61
+ > Unlayered styles **always** beat layered ones in the cascade, regardless of specificity. So `* { margin: 0 }` outranks Anta's `caption { margin-bottom: 0.25em }`, `p { margin: 0 0 1em }`, `ul / ol` padding, and any other per-element default Anta provides — even though those use stronger selectors.
62
+ >
63
+ > If you're importing `@antadesign/anta/reset.css`, Anta already does the same universal `box-sizing` and margin reset, *inside* `@layer anta`. The element-level rules sitting on top are intentionally polite defaults — sensible out of the box, trivially overridable when you want something else (any rule in `@layer components` / `@layer utilities`, or any unlayered rule of your own that targets specific elements, wins automatically). **Delete the duplicate hard reset from your global CSS** so those defaults can apply. If you want to keep your own reset, wrap it in `@layer base { … }` so it sits below `anta` in the declared order and Anta's rules still win element-by-element.
64
+
52
65
  ## Registering elements
53
66
 
54
67
  The JSX wrappers (React components) as `Progress` render custom DOM elements as `<a-progress>`. The custom elements themselves must be registered with the browser **before** they appear in the DOM, and registration only works where `HTMLElement` exists — i.e. the UI thread of a real browser. **Node.js (SSR) and Worker threads don't have `HTMLElement`**, so the import is harmless in those environments: it does nothing — registration is skipped silently and the class uses a stand-in base instead of crashing — though it might extend your worker's bundle size a bit.
@@ -4,6 +4,9 @@ export interface TextProps extends BaseProps {
4
4
  priority?: 'primary' | 'secondary' | 'tertiary' | 'quaternary' | 'quinary';
5
5
  /** Color tint. Applies the matching `--text-{N}-{tone}` palette. */
6
6
  tone?: 'brand' | 'success' | 'critical' | 'warning' | 'info';
7
+ /** Type scale. `small` = 13/16, `medium` = 15/20, `large` = 17/24.
8
+ * @defaultValue medium */
9
+ size?: 'small' | 'medium' | 'large';
7
10
  /** Render as inline-block instead of the default block element. */
8
11
  inline?: boolean;
9
12
  /** Truncate with a trailing ellipsis. `true` (or `1`) clamps to a
@@ -39,4 +42,4 @@ export interface TextProps extends BaseProps {
39
42
  * <Text truncate={3} expandable>…long paragraph…</Text>
40
43
  * ```
41
44
  */
42
- export declare const Text: ({ priority, tone, inline, truncate, expandable, className, style, children, ...rest }: TextProps) => any;
45
+ export declare const Text: ({ priority, tone, size, inline, truncate, expandable, className, style, children, ...rest }: TextProps) => any;
@@ -1,5 +1,5 @@
1
1
  import { jsx } from "@antadesign/anta/jsx-runtime";
2
- const Text = ({ priority, tone, inline, truncate, expandable, className, style, children, ...rest }) => {
2
+ const Text = ({ priority, tone, size, inline, truncate, expandable, className, style, children, ...rest }) => {
3
3
  const lineCount = typeof truncate === "number" ? truncate : truncate ? 1 : null;
4
4
  const computedStyle = lineCount != null ? { ...style, ["--line-clamp"]: lineCount } : style;
5
5
  return /* @__PURE__ */ jsx(
@@ -7,6 +7,7 @@ const Text = ({ priority, tone, inline, truncate, expandable, className, style,
7
7
  {
8
8
  priority,
9
9
  tone,
10
+ size,
10
11
  inline: inline ? "" : void 0,
11
12
  truncate: lineCount != null ? String(lineCount) : void 0,
12
13
  expandable: expandable && truncate ? "" : void 0,
@@ -0,0 +1,41 @@
1
+ import type { BaseProps } from "../general_types";
2
+ export interface TitleProps extends BaseProps {
3
+ /** Heading level, 1-6. Drives font-size, line-height, and vertical
4
+ * rhythm. Also surfaced to assistive tech via `aria-level`. Defaults
5
+ * to 2 (h1 is typically reserved for the page title). */
6
+ level?: 1 | 2 | 3 | 4 | 5 | 6;
7
+ /** Visual priority. Maps to text-1..text-5. Defaults to 'primary' (text-1). */
8
+ priority?: 'primary' | 'secondary' | 'tertiary' | 'quaternary' | 'quinary';
9
+ /** Color tint. Applies the matching `--text-{N}-{tone}` palette. */
10
+ tone?: 'brand' | 'success' | 'critical' | 'warning' | 'info';
11
+ }
12
+ /**
13
+ * Block-level heading with level 1-6, priority, and tone.
14
+ *
15
+ * Renders an `<a-title>` styled tag (no JS, no shadow DOM) with
16
+ * `role="heading"` and `aria-level={level}` set by this wrapper for
17
+ * accessibility. Children can be anything — text, icons, badges, links
18
+ * — so there are no `leadingIcon` / `trailingIcon` props; just compose
19
+ * inside.
20
+ *
21
+ * Raw `<h1>`-`<h6>` get the same visual styling via `src/reset.css`,
22
+ * so use a real heading tag if SEO matters and you don't need the
23
+ * `tone` / `priority` props.
24
+ *
25
+ * Requires `@antadesign/anta/elements` to be imported (client-side only)
26
+ * so the CSS ships with the page.
27
+ *
28
+ * @example Basic usage
29
+ * ```tsx
30
+ * <Title level={1}>Page title</Title>
31
+ * <Title level={2} tone="brand">Section</Title>
32
+ * ```
33
+ *
34
+ * @example With children beyond text
35
+ * ```tsx
36
+ * <Title level={3}>
37
+ * <Icon shape="bookmark" /> Saved items
38
+ * </Title>
39
+ * ```
40
+ */
41
+ export declare const Title: ({ level, priority, tone, className, style, children, ...rest }: TitleProps) => any;
@@ -0,0 +1,20 @@
1
+ import { jsx } from "@antadesign/anta/jsx-runtime";
2
+ const Title = ({ level = 2, priority, tone, className, style, children, ...rest }) => {
3
+ return /* @__PURE__ */ jsx(
4
+ "a-title",
5
+ {
6
+ level: String(level),
7
+ priority,
8
+ tone,
9
+ role: "heading",
10
+ "aria-level": level,
11
+ class: className,
12
+ style,
13
+ ...rest,
14
+ children
15
+ }
16
+ );
17
+ };
18
+ export {
19
+ Title
20
+ };
@@ -1,5 +1,10 @@
1
1
  @layer anta {
2
2
  a-icon {
3
+ /* `<a-icon size="N">` maps to `--icon-size` via typed `attr()`
4
+ (CSS Values 5) — Chrome 133+, Safari 18.2+. Firefox not yet:
5
+ in raw HTML usage there, set `style="--icon-size: Npx"`. */
6
+ --icon-size: attr(size px);
7
+
3
8
  display: inline-block;
4
9
  vertical-align: middle;
5
10
  width: var(--icon-size, 16px);
@@ -1,3 +1,4 @@
1
+ import type { IconShapes } from '@antadesign/anta';
1
2
  export declare const ICON_SHAPES: readonly ["arrow-left-to-line", "arrow-left", "arrow-narrow-down", "arrow-narrow-up-down", "arrow-narrow-up", "arrow-right", "arrow-top-right", "asterisk", "book-open", "braces", "bug", "calendar", "case-sensitive", "chat", "check", "chevron-down", "chevron-left", "chevron-right", "chevron-up", "chevrons-right", "circle-check", "circle-large", "circle", "click", "clock", "cloud-upload", "copy", "corner-down-right", "cube", "dots-vertical", "download", "edit", "education-disk", "external-link", "file-down", "file", "filter", "folder-close", "folder-open", "folder-tree", "github-logo", "gitlab-logo", "hat-glasses", "heart-handshake", "help-disk", "history-tree", "history", "home", "hourglass", "info", "jira-logo", "linear-logo", "link", "list-detail-view", "maximize", "megaphone", "menu", "minimize", "minus", "moon", "more", "move-horizontal", "not-equal", "play", "plus", "presentation", "refresh-ccw-dot", "refresh", "regex", "repeat", "rss", "runs-history", "scroll-text", "search-check", "search", "send", "sparkles", "sun", "swatch-book", "table-2", "text-highlight", "text-initial", "timer", "trash", "trello-logo", "view", "warning-triangle", "webhook", "workflow", "x"];
2
3
  export declare const ICON_SYNONYMS: Readonly<Record<string, readonly string[]>>;
3
4
  declare module '@antadesign/anta' {
@@ -94,4 +95,4 @@ declare module '@antadesign/anta' {
94
95
  'x': true;
95
96
  }
96
97
  }
97
- export type IconShape = keyof import('@antadesign/anta').IconShapes;
98
+ export type IconShape = keyof IconShapes;
@@ -3,11 +3,17 @@
3
3
  --text-color: var(--text-1);
4
4
  --text-link-color: var(--link-color);
5
5
  --text-link-hover: var(--link-color-hover);
6
-
6
+
7
7
  display: block;
8
8
  color: var(--text-color);
9
+ font-size: 15px;
10
+ line-height: 20px;
9
11
  }
10
-
12
+
13
+ a-text[size="small"] { font-size: 13px; line-height: 16px; }
14
+ a-text[size="medium"] { font-size: 15px; line-height: 20px; }
15
+ a-text[size="large"] { font-size: 17px; line-height: 24px; }
16
+
11
17
  a-text[inline] {
12
18
  display: inline-block;
13
19
  }
@@ -0,0 +1,64 @@
1
+ @layer anta {
2
+ /* `<a-title>` is intentionally CSS-only — no JS, no shadow DOM, no
3
+ `customElements.define`. The browser treats it as a generic unknown
4
+ element; the rules below give it block layout, the demi-bold
5
+ variable-font weight, and a per-level type scale + vertical rhythm.
6
+ The matching `h1`-`h6` rules in `src/reset.css` are kept in lockstep
7
+ so raw markup looks the same as `<Title level={n}>`. */
8
+
9
+ a-title {
10
+ display: block;
11
+ color: var(--text-1);
12
+ font-weight: 584.62;
13
+ letter-spacing: 0;
14
+ text-wrap: balance;
15
+ }
16
+
17
+ a-title a-icon {
18
+ transform: translateY(-0.05em);
19
+ }
20
+
21
+ a-title[level="1"] { font-size: 28px; line-height: 32px; margin-block-start: 0; margin-block-end: 16px; }
22
+ a-title[level="2"] { font-size: 24px; line-height: 28px; margin-block-start: 32px; margin-block-end: 12px; }
23
+ a-title[level="3"] { font-size: 20px; line-height: 24px; margin-block-start: 24px; margin-block-end: 12px; }
24
+ a-title[level="4"] { font-size: 17px; line-height: 20px; margin-block-start: 20px; margin-block-end: 8px; }
25
+ a-title[level="5"] { font-size: 15px; line-height: 20px; margin-block-start: 16px; margin-block-end: 8px; }
26
+ a-title[level="6"] { font-size: 13px; line-height: 16px; margin-block-start: 16px; margin-block-end: 4px; }
27
+
28
+ /* Neutral priority overrides. */
29
+ a-title[priority="secondary"] { color: var(--text-2); }
30
+ a-title[priority="tertiary"] { color: var(--text-3); }
31
+ a-title[priority="quaternary"] { color: var(--text-4); }
32
+ a-title[priority="quinary"] { color: var(--text-5); }
33
+
34
+ /* Tinted — same shape as a-text's tone × priority matrix. */
35
+ a-title[tone="brand"] { color: var(--text-1-brand); }
36
+ a-title[tone="brand"][priority="secondary"] { color: var(--text-2-brand); }
37
+ a-title[tone="brand"][priority="tertiary"] { color: var(--text-3-brand); }
38
+ a-title[tone="brand"][priority="quaternary"] { color: var(--text-4-brand); }
39
+ a-title[tone="brand"][priority="quinary"] { color: var(--text-5-brand); }
40
+
41
+ a-title[tone="success"] { color: var(--text-1-success); }
42
+ a-title[tone="success"][priority="secondary"] { color: var(--text-2-success); }
43
+ a-title[tone="success"][priority="tertiary"] { color: var(--text-3-success); }
44
+ a-title[tone="success"][priority="quaternary"] { color: var(--text-4-success); }
45
+ a-title[tone="success"][priority="quinary"] { color: var(--text-5-success); }
46
+
47
+ a-title[tone="critical"] { color: var(--text-1-critical); }
48
+ a-title[tone="critical"][priority="secondary"] { color: var(--text-2-critical); }
49
+ a-title[tone="critical"][priority="tertiary"] { color: var(--text-3-critical); }
50
+ a-title[tone="critical"][priority="quaternary"] { color: var(--text-4-critical); }
51
+ a-title[tone="critical"][priority="quinary"] { color: var(--text-5-critical); }
52
+
53
+ a-title[tone="warning"] { color: var(--text-1-warning); }
54
+ a-title[tone="warning"][priority="secondary"] { color: var(--text-2-warning); }
55
+ a-title[tone="warning"][priority="tertiary"] { color: var(--text-3-warning); }
56
+ a-title[tone="warning"][priority="quaternary"] { color: var(--text-4-warning); }
57
+ a-title[tone="warning"][priority="quinary"] { color: var(--text-5-warning); }
58
+
59
+ a-title[tone="info"] { color: var(--text-1-info); }
60
+ a-title[tone="info"][priority="secondary"] { color: var(--text-2-info); }
61
+ a-title[tone="info"][priority="tertiary"] { color: var(--text-3-info); }
62
+ a-title[tone="info"][priority="quaternary"] { color: var(--text-4-info); }
63
+ a-title[tone="info"][priority="quinary"] { color: var(--text-5-info); }
64
+ }
@@ -1,5 +1,6 @@
1
1
  import './a-progress.css';
2
2
  import './a-text.css';
3
+ import './a-title.css';
3
4
  import './a-icon.css';
4
5
  import './a-icon.shapes.css';
5
6
  export { AProgressElement, register_a_progress } from './a-progress';
@@ -3,6 +3,7 @@ import { register_a_text } from "./a-text";
3
3
  import { register_a_icon } from "./a-icon";
4
4
  import "./a-progress.css";
5
5
  import "./a-text.css";
6
+ import "./a-title.css";
6
7
  import "./a-icon.css";
7
8
  import "./a-icon.shapes.css";
8
9
  import { AProgressElement, register_a_progress as register_a_progress2 } from "./a-progress";
@@ -60,6 +60,8 @@ export interface ATextAttributes extends BaseAttributes {
60
60
  priority?: 'primary' | 'secondary' | 'tertiary' | 'quaternary' | 'quinary';
61
61
  /** Color tint. Applies the matching `--text-{N}-{tone}` palette. */
62
62
  tone?: 'brand' | 'success' | 'critical' | 'warning' | 'info';
63
+ /** Type scale. `small` = 13/16, `medium` (default) = 15/20, `large` = 17/24. */
64
+ size?: 'small' | 'medium' | 'large';
63
65
  /** Render as inline-block instead of the default block. */
64
66
  inline?: boolean | string;
65
67
  /** Truncate to N lines with a trailing ellipsis. The attribute value
@@ -73,6 +75,25 @@ export interface ATextAttributes extends BaseAttributes {
73
75
  /** ARIA disclosure state, mirrors the JSX wrapper's `expanded` flag. */
74
76
  'aria-expanded'?: boolean | 'true' | 'false';
75
77
  }
78
+ /**
79
+ * Attributes for the `<a-title>` styled tag.
80
+ *
81
+ * `<a-title>` has no JS — it's a CSS-only styled element. Low-level
82
+ * attributes; for the JSX wrapper with typed `level` numbers and ARIA
83
+ * use `Title` from `@antadesign/anta`.
84
+ */
85
+ export interface ATitleAttributes extends BaseAttributes {
86
+ /** Heading level as a string attribute, '1'-'6'. */
87
+ level?: string;
88
+ /** Visual priority. Maps to text-1..text-5. */
89
+ priority?: 'primary' | 'secondary' | 'tertiary' | 'quaternary' | 'quinary';
90
+ /** Color tint. Applies the matching `--text-{N}-{tone}` palette. */
91
+ tone?: 'brand' | 'success' | 'critical' | 'warning' | 'info';
92
+ /** ARIA role — the JSX wrapper sets this to `'heading'`. */
93
+ role?: string;
94
+ /** ARIA heading level — the JSX wrapper sets this to match `level`. */
95
+ 'aria-level'?: number | string;
96
+ }
76
97
  /**
77
98
  * Attributes for the `<a-icon>` custom element. The `shape` attribute
78
99
  * value is typed as `string` here so the element accepts any consumer's
@@ -81,6 +102,16 @@ export interface ATextAttributes extends BaseAttributes {
81
102
  export interface AIconAttributes extends BaseAttributes {
82
103
  /** Which icon to render. */
83
104
  shape?: string;
105
+ /** Width and height in pixels. Mapped to the `--icon-size` custom
106
+ * property via the CSS Values 5 typed `attr()` function — Chrome
107
+ * 133+ and Safari 18.2+ only. Firefox hasn't shipped typed
108
+ * `attr()` yet, so on raw `<a-icon size="N">` the attribute is
109
+ * silently ignored there and the icon stays at the default 16 ×
110
+ * 16. For cross-browser sizing in pure-HTML usage, set the
111
+ * variable inline: `<a-icon style="--icon-size: 24px">`. The JSX
112
+ * `<Icon size={N}>` wrapper already does that under the hood and
113
+ * is the recommended path. */
114
+ size?: number | string;
84
115
  /** ARIA role — the JSX wrapper sets `'img'` when a label is provided. */
85
116
  role?: string;
86
117
  /** ARIA accessible name when the icon carries meaning. */
@@ -63,7 +63,7 @@ export async function generate({ input, output = '.', name = 'a-icon.shapes', in
63
63
  // built-ins; consumers who want their icons unlayered can post-
64
64
  // process the output.
65
65
  const cssLines = [
66
- '/* Auto-generated by scripts/generate-icons.mjs. Do not edit by hand. */',
66
+ '/* Auto-generated by @antadesign/anta. Do not edit by hand. */',
67
67
  '',
68
68
  '@layer anta {',
69
69
  '',
@@ -132,7 +132,9 @@ export async function generate({ input, output = '.', name = 'a-icon.shapes', in
132
132
 
133
133
  const synonymsEntries = Object.entries(synonyms)
134
134
  const tsLines = [
135
- '/* Auto-generated by scripts/generate-icons.mjs. Do not edit by hand. */',
135
+ '/* Auto-generated by @antadesign/anta. Do not edit by hand. */',
136
+ '',
137
+ "import type { IconShapes } from '@antadesign/anta'",
136
138
  '',
137
139
  'export const ICON_SHAPES = [',
138
140
  ...shapes.map((s) => ` '${s}',`),
@@ -150,7 +152,7 @@ export async function generate({ input, output = '.', name = 'a-icon.shapes', in
150
152
  ' }',
151
153
  '}',
152
154
  '',
153
- "export type IconShape = keyof import('@antadesign/anta').IconShapes",
155
+ 'export type IconShape = keyof IconShapes',
154
156
  '',
155
157
  ]
156
158
  fs.writeFileSync(tsPath, tsLines.join('\n'))
package/dist/index.d.ts CHANGED
@@ -20,6 +20,8 @@ export { Progress } from './components/Progress';
20
20
  export type { ProgressProps } from './components/Progress';
21
21
  export { Text } from './components/Text';
22
22
  export type { TextProps } from './components/Text';
23
+ export { Title } from './components/Title';
24
+ export type { TitleProps } from './components/Title';
23
25
  export { Icon } from './components/Icon';
24
26
  export type { IconProps } from './components/Icon';
25
27
  export { ICON_SHAPES, ICON_SYNONYMS } from './elements/a-icon.shapes';
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { Progress } from "./components/Progress";
2
2
  import { Text } from "./components/Text";
3
+ import { Title } from "./components/Title";
3
4
  import { Icon } from "./components/Icon";
4
5
  import { ICON_SHAPES, ICON_SYNONYMS } from "./elements/a-icon.shapes";
5
6
  import { configure } from "./jsx-runtime";
@@ -9,5 +10,6 @@ export {
9
10
  Icon,
10
11
  Progress,
11
12
  Text,
13
+ Title,
12
14
  configure
13
15
  };
@@ -22,7 +22,7 @@ export declare function configure(jsx: JsxFunction, Fragment?: ComponentType): v
22
22
  export declare function jsx(type: ComponentType, props: Record<string, unknown> | null, key?: string | number): unknown;
23
23
  export declare function jsxs(type: ComponentType, props: Record<string, unknown> | null, key?: string | number): unknown;
24
24
  export { _Fragment as Fragment };
25
- import type { AProgressAttributes, ATextAttributes, AIconAttributes, BaseAttributes } from './general_types';
25
+ import type { AProgressAttributes, ATextAttributes, ATitleAttributes, AIconAttributes, BaseAttributes } from './general_types';
26
26
  export declare namespace JSX {
27
27
  type IntrinsicElements = React.JSX.IntrinsicElements & {
28
28
  'a-progress': AProgressAttributes;
@@ -31,6 +31,7 @@ export declare namespace JSX {
31
31
  'a-progress-text': BaseAttributes;
32
32
  'a-progress-hint': BaseAttributes;
33
33
  'a-text': ATextAttributes;
34
+ 'a-title': ATitleAttributes;
34
35
  'a-icon': AIconAttributes;
35
36
  };
36
37
  }
package/dist/reset.css CHANGED
@@ -52,10 +52,22 @@
52
52
 
53
53
  /* ───── Typography defaults — Anta opinion ───────────────────── */
54
54
 
55
+ /* Raw headings adopt the same visual scale as `<Title level={n}>`
56
+ so plain markup matches the component. Values are duplicated in
57
+ `src/elements/a-title.css`; keep the two in lockstep. */
55
58
  h1, h2, h3, h4, h5, h6 {
56
- font-weight: 600;
59
+ color: var(--text-1);
60
+ font-weight: 584.62;
61
+ letter-spacing: 0;
57
62
  }
58
63
 
64
+ h1 { font-size: 28px; line-height: 32px; margin-block: 0 16px; }
65
+ h2 { font-size: 24px; line-height: 28px; margin-block: 32px 12px; }
66
+ h3 { font-size: 20px; line-height: 24px; margin-block: 24px 12px; }
67
+ h4 { font-size: 17px; line-height: 20px; margin-block: 20px 8px; }
68
+ h5 { font-size: 15px; line-height: 20px; margin-block: 16px 8px; }
69
+ h6 { font-size: 13px; line-height: 16px; margin-block: 16px 4px; }
70
+
59
71
  strong {
60
72
  font-weight: 600;
61
73
  }
@@ -112,4 +124,79 @@
112
124
  a:active {
113
125
  text-decoration-color: color-mix(in oklch, currentColor 75%, transparent);
114
126
  }
127
+
128
+ /* Text selection — full-chroma brand color at 15% alpha. Using
129
+ OKLCH relative-color syntax (not `color-mix` with `transparent`)
130
+ keeps the chroma intact: mixing toward `transparent` interpolates
131
+ in OKLCH and pulls L/C toward zero, which washes the result out.
132
+ `calc(c * 1.5)` bumps the saturation modestly above the source
133
+ token so the highlight reads as clearly brand-coloured rather
134
+ than a neutral grey. No `color` override on the selection, so
135
+ the selected text keeps its original color and contrast is
136
+ preserved automatically. `--text-1-brand` inverts between light
137
+ and dark, so the effect tracks the active palette unaided. */
138
+ ::selection {
139
+ background: oklch(from var(--text-1-brand) l calc(c * 1.5) h / 0.15);
140
+ }
141
+
142
+ /* ───── Tables ───────────────────────────────────────────────── */
143
+
144
+ /* Polite, element-level baseline. Rules live in `@layer anta`, so
145
+ any consumer rule outside a layer — or in `components` /
146
+ `utilities` — overrides without effort. Width is intentionally
147
+ left untouched so app tables stay inline-sized; full-bleed is a
148
+ decision for the surrounding page. */
149
+ table {
150
+ border-collapse: collapse;
151
+ font-variant-numeric: tabular-nums;
152
+ }
153
+
154
+ caption {
155
+ text-align: left;
156
+ color: var(--text-3);
157
+ padding-left: 10px;
158
+ margin-bottom: 0.25em;
159
+ }
160
+
161
+ th, td {
162
+ padding: 5px 10px;
163
+ text-align: left;
164
+ vertical-align: top;
165
+ border-bottom: 1px solid var(--border-5);
166
+ }
167
+
168
+ thead th {
169
+ font-weight: 600;
170
+ }
171
+
172
+ /* Drop the trailing hairline under the table's last row so the
173
+ table doesn't end with an orphan line. Handles both "tbody is
174
+ the final section" and "tfoot is the final section". */
175
+ tfoot tr:last-child > :is(th, td),
176
+ table:not(:has(tfoot)) tbody tr:last-child > :is(th, td) {
177
+ border-bottom: none;
178
+ }
179
+
180
+ /* Opt-in: outer frame + vertical column dividers + 3px rounded
181
+ corners. Switches to separate borders because `border-radius`
182
+ doesn't render reliably under `border-collapse: collapse` — the
183
+ collapsed borders override the radius. Cells draw their own
184
+ right edges to build the internal grid; the last cell in each
185
+ row drops its right border so the table's own border supplies
186
+ the outer frame. Row separators come from the baseline
187
+ `border-bottom` and continue to work under separate-collapse. */
188
+ table[data-bordered] {
189
+ border-collapse: separate;
190
+ border-spacing: 0;
191
+ border: 1px solid var(--border-5);
192
+ border-radius: 3px;
193
+ }
194
+
195
+ table[data-bordered] :is(th, td) {
196
+ border-right: 1px solid var(--border-5);
197
+ }
198
+
199
+ table[data-bordered] tr > :is(th, td):last-child {
200
+ border-right: 0;
201
+ }
115
202
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antadesign/anta",
3
- "version": "0.1.1-dev.5",
3
+ "version": "0.1.1-dev.6",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -36,8 +36,8 @@
36
36
  },
37
37
  "scripts": {
38
38
  "build": "pnpm run build:js && pnpm run build:css && pnpm run build:types",
39
- "build:css": "cp src/elements/a-progress.css src/elements/a-text.css src/elements/a-icon.css src/elements/a-icon.shapes.css dist/elements/ && cp src/components/Progress.module.css src/components/Text.module.css dist/components/ && cp src/tokens.css src/reset.css dist/ && cp scripts/generate-icons.mjs dist/",
40
- "build:js": "esbuild src/components/Progress.tsx src/components/Text.tsx src/components/Icon.tsx src/index.ts src/jsx-runtime.ts src/general_types.ts src/anta_helpers.ts src/elements/index.ts src/elements/a-progress.ts src/elements/a-text.ts src/elements/a-icon.ts src/elements/a-icon.shapes.ts --outdir=dist --outbase=src --jsx=automatic --jsx-import-source=@antadesign/anta --format=esm --target=ES2022 --loader:.module.css=local-css --loader:.css=global-css",
39
+ "build:css": "cp src/elements/a-progress.css src/elements/a-text.css src/elements/a-title.css src/elements/a-icon.css src/elements/a-icon.shapes.css dist/elements/ && cp src/components/Progress.module.css src/components/Text.module.css dist/components/ && cp src/tokens.css src/reset.css dist/ && cp scripts/generate-icons.mjs dist/",
40
+ "build:js": "esbuild src/components/Progress.tsx src/components/Text.tsx src/components/Title.tsx src/components/Icon.tsx src/index.ts src/jsx-runtime.ts src/general_types.ts src/anta_helpers.ts src/elements/index.ts src/elements/a-progress.ts src/elements/a-text.ts src/elements/a-icon.ts src/elements/a-icon.shapes.ts --outdir=dist --outbase=src --jsx=automatic --jsx-import-source=@antadesign/anta --format=esm --target=ES2022 --loader:.module.css=local-css --loader:.css=global-css",
41
41
  "build:types": "tsc -p src/tsconfig.json",
42
42
  "typecheck": "tsc --noEmit -p src/tsconfig.json",
43
43
  "icons": "node scripts/generate-icons.mjs --input src/elements/icons --output src/elements --name a-icon.shapes --internal",