agnosticui-core 2.0.0-alpha.2 → 2.0.0-alpha.4
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 +67 -33
- package/dist/components/Button/core/_Button.d.ts.map +1 -1
- package/dist/components/Button/core/_Button.js +52 -5
- package/dist/components/Timeline/react/ReactTimeline.d.ts +23 -9
- package/dist/components/Timeline/react/ReactTimeline.d.ts.map +1 -1
- package/dist/components/Timeline/react/ReactTimeline.js +18 -14
- package/dist/styles/ag-tokens.css +1 -0
- package/package.json +1 -13
- package/src/components/Button/core/_Button.ts +48 -1
- package/src/components/Drawer/v1/dialog--drawer-bottom.hbs +48 -0
- package/src/components/Drawer/v1/dialog--drawer-end.hbs +48 -0
- package/src/components/Drawer/v1/dialog--drawer-start.hbs +48 -0
- package/src/components/Drawer/v1/dialog--drawer-top.hbs +48 -0
- package/src/components/Drawer/v1/dialog-demo.css +13 -0
- package/src/components/Drawer/v1/dialog.config.yml +5 -0
- package/src/components/Drawer/v1/dialog.css +99 -0
- package/src/components/Drawer/v1/dialog.hbs +48 -0
- package/src/components/Drawer/v1/drawer-animations.css +52 -0
- package/src/components/Drawer/v1/drawer.css +50 -0
- package/src/components/Timeline/react/ReactTimeline.tsx +47 -24
- package/src/styles/ag-tokens.css +1 -0
- package/RTL_IMPLEMENTATION_PLAN.md +0 -295
- package/dist/global.d.js +0 -1
- package/src/global.d.ts +0 -43
package/README.md
CHANGED
|
@@ -23,41 +23,75 @@ AgnosticUI uses a **Minimalist & Highly Themeable** architecture where component
|
|
|
23
23
|
|
|
24
24
|
```
|
|
25
25
|
src/components/
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
│
|
|
29
|
-
│
|
|
30
|
-
│ ├──
|
|
31
|
-
│
|
|
32
|
-
|
|
33
|
-
│ ├──
|
|
34
|
-
│
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
26
|
+
└── Accordion/
|
|
27
|
+
├── core/
|
|
28
|
+
│ ├── _Accordion.ts # Core Lit Component
|
|
29
|
+
│ ├── Accordion.ts # Public interface
|
|
30
|
+
│ ├── AccordionGroup.ts # Group component
|
|
31
|
+
│ └── README.md # Documentation
|
|
32
|
+
├── react/
|
|
33
|
+
│ ├── index.ts # React exports
|
|
34
|
+
│ └── ReactAccordion.tsx # React wrapper
|
|
35
|
+
└── vue/
|
|
36
|
+
├── index.ts # Vue exports
|
|
37
|
+
├── VueAccordion.vue # Main component
|
|
38
|
+
├── VueAccordionContent.vue # Content component
|
|
39
|
+
├── VueAccordionHeader.vue # Header component
|
|
40
|
+
└── VueAccordionItem.vue # Item component
|
|
40
41
|
```
|
|
41
42
|
|
|
42
|
-
##
|
|
43
|
-
|
|
44
|
-
###
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
-
|
|
59
|
-
-
|
|
60
|
-
-
|
|
43
|
+
## Why AgnosticUI?
|
|
44
|
+
|
|
45
|
+
### The Local UI Kit - A New Category
|
|
46
|
+
**The UI kit that lives in your codebase, not node_modules.**
|
|
47
|
+
|
|
48
|
+
Traditional UI libraries live in `node_modules/` as black boxes. Copy/paste approaches give you code but no reference. AgnosticUI Local gives you **both**: a complete reference library in your project plus owned copies of components you use.
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
npx ag init # Full library in ./agnosticui/ (reference)
|
|
52
|
+
npx ag add button # Component in ./src/components/ag/ (yours to modify)
|
|
53
|
+
npx ag sync # Update reference, preserve your customizations
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### AI-First Development
|
|
57
|
+
**The only UI kit designed for AI-assisted development.**
|
|
58
|
+
|
|
59
|
+
- **Full Context**: AI tools (Cursor, Windsurf, Claude) see your entire component library
|
|
60
|
+
- **Better Assistance**: "Make this button work like the Combobox" - AI sees both
|
|
61
|
+
- **Reference + Customization**: AI understands the source AND your modifications
|
|
62
|
+
- **Offline & Local**: No API calls, no rate limits, no black boxes
|
|
63
|
+
|
|
64
|
+
### Complete Ownership
|
|
65
|
+
**Copy, modify, and own your components.**
|
|
66
|
+
|
|
67
|
+
- Components copied to your project - modify structure, behavior, styling
|
|
68
|
+
- No vendor lock-in or "black box" frustration
|
|
69
|
+
- You control the dependency graph and update schedule
|
|
70
|
+
- Review diffs before accepting updates via `npx ag sync`
|
|
71
|
+
|
|
72
|
+
### Zero Dependencies
|
|
73
|
+
**Only Lit (5KB runtime) - nothing else.**
|
|
74
|
+
|
|
75
|
+
- No bloated node_modules
|
|
76
|
+
- Components work standalone
|
|
77
|
+
- Production bundle includes only what you use
|
|
78
|
+
- Framework wrappers via @lit/react and Vue 3 composition API
|
|
79
|
+
|
|
80
|
+
### Minimalist & Themeable
|
|
81
|
+
**Beautiful defaults, infinite customization.**
|
|
82
|
+
|
|
83
|
+
- Production-ready styling out of the box
|
|
84
|
+
- Everything customizable via `--ag-*` design tokens
|
|
85
|
+
- Enterprise white-labeling capability
|
|
86
|
+
- Light/dark mode built-in
|
|
87
|
+
|
|
88
|
+
### Multi-Framework Support
|
|
89
|
+
**React, Vue, Lit - one component library, all frameworks.**
|
|
90
|
+
|
|
91
|
+
- Framework-specific wrappers for optimal developer experience
|
|
92
|
+
- React wrapper via @lit/react makes props and events feel naturally "React-like"
|
|
93
|
+
- Vue 3 components using composition API
|
|
94
|
+
- Svelte works directly (excellent Web Components support)
|
|
61
95
|
|
|
62
96
|
## Usage
|
|
63
97
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_Button.d.ts","sourceRoot":"","sources":["../../../../src/components/Button/core/_Button.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,UAAU,EAAa,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAKjE,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,OAAO,CAAC;CAClB;AACD,MAAM,MAAM,iBAAiB,GAAG,WAAW,CAAC,uBAAuB,CAAC,CAAC;AAGrE,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,QAAQ,GAAG,YAAY,GAAG,EAAE,CAAC;IACzF,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1C,KAAK,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,gBAAgB,GAAG,EAAE,CAAC;IAC5E,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC;IACrC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IACtC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IACtC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IACrC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;CAC/C;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,QAAS,SAAQ,UAAW,YAAW,WAAW;IAC7D,MAAM,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"_Button.d.ts","sourceRoot":"","sources":["../../../../src/components/Button/core/_Button.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,UAAU,EAAa,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAKjE,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,OAAO,CAAC;CAClB;AACD,MAAM,MAAM,iBAAiB,GAAG,WAAW,CAAC,uBAAuB,CAAC,CAAC;AAGrE,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,QAAQ,GAAG,YAAY,GAAG,EAAE,CAAC;IACzF,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1C,KAAK,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,gBAAgB,GAAG,EAAE,CAAC;IAC5E,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC;IACrC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IACtC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IACtC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IACrC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;CAC/C;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,QAAS,SAAQ,UAAW,YAAW,WAAW;IAC7D,MAAM,CAAC,MAAM,EA2WR,cAAc,CAAC;IAEpB;;OAEG;IAEK,OAAO,EAAE,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,YAAY,GAAG,EAAE,CAAC;IAEhG;;OAEG;IAEK,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAEjD;;OAEG;IAEK,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,gBAAgB,GAAG,EAAE,CAAC;IAEnF;;OAEG;IAEK,QAAQ,EAAE,OAAO,CAAC;IAE1B;;OAEG;IAEK,KAAK,EAAE,OAAO,CAAC;IAEvB;;OAEG;IAEK,IAAI,EAAE,OAAO,CAAC;IAEtB;;OAEG;IAEK,OAAO,EAAE,OAAO,CAAC;IAEzB;;OAEG;IAEK,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC;IAE5C;;OAEG;IAEK,QAAQ,EAAE,OAAO,CAAC;IAE1B;;OAEG;IAEK,OAAO,EAAE,OAAO,CAAC;IAEzB;;OAEG;IAEK,MAAM,EAAE,OAAO,CAAC;IAExB;;OAEG;IAEK,OAAO,EAAE,OAAO,CAAC;IAEzB;;OAEG;IAEK,SAAS,EAAE,MAAM,CAAC;IAGlB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IAGtC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IAGtC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IAGrC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;;IAmBtD,OAAO,CAAC,YAAY;IAwBpB,OAAO,CAAC,YAAY;IAcpB,OAAO,CAAC,WAAW;IAcnB;;OAEG;IACH,KAAK;IAOL;;OAEG;IACH,IAAI;IAOJ,MAAM;CAoBP"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LitElement as
|
|
1
|
+
import { LitElement as l, css as c, html as h } from "lit";
|
|
2
2
|
import { n as a } from "../../../property-CemaeiRl.js";
|
|
3
3
|
import { o as i } from "../../../if-defined-C8i28hSj.js";
|
|
4
4
|
var b = Object.defineProperty, o = (g, r, e, v) => {
|
|
@@ -6,7 +6,7 @@ var b = Object.defineProperty, o = (g, r, e, v) => {
|
|
|
6
6
|
(u = g[s]) && (n = u(r, e, n) || n);
|
|
7
7
|
return n && b(r, e, n), n;
|
|
8
8
|
};
|
|
9
|
-
const d = class d extends
|
|
9
|
+
const d = class d extends l {
|
|
10
10
|
constructor() {
|
|
11
11
|
super(), this.disabled = !1, this.loading = !1, this.toggle = !1, this.pressed = !1, this.bordered = !1, this.ghost = !1, this.link = !1, this.grouped = !1, this.type = "button", this.ariaLabel = "", this.variant = "", this.size = "md", this.shape = "";
|
|
12
12
|
}
|
|
@@ -53,7 +53,7 @@ const d = class d extends h {
|
|
|
53
53
|
}
|
|
54
54
|
render() {
|
|
55
55
|
const r = this.disabled || this.loading;
|
|
56
|
-
return
|
|
56
|
+
return h`
|
|
57
57
|
<button
|
|
58
58
|
type=${this.type}
|
|
59
59
|
part="ag-button"
|
|
@@ -71,7 +71,7 @@ const d = class d extends h {
|
|
|
71
71
|
`;
|
|
72
72
|
}
|
|
73
73
|
};
|
|
74
|
-
d.styles =
|
|
74
|
+
d.styles = c`
|
|
75
75
|
/* MINIMALIST & THEMEABLE - Styling via --ag-* design tokens */
|
|
76
76
|
:host {
|
|
77
77
|
/* Inline-flex for perfect centering while maintaining inline behavior */
|
|
@@ -375,9 +375,56 @@ d.styles = l`
|
|
|
375
375
|
background: var(--ag-background-secondary);
|
|
376
376
|
}
|
|
377
377
|
|
|
378
|
+
/* Disabled states - per-variant to maintain tonal identity */
|
|
379
|
+
|
|
380
|
+
/* Filled buttons - use lighter background tokens */
|
|
381
|
+
:host([variant="primary"]) button:disabled {
|
|
382
|
+
background: var(--ag-primary-background);
|
|
383
|
+
color: var(--ag-primary-text);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
:host([variant="success"]) button:disabled {
|
|
387
|
+
background: var(--ag-success-background);
|
|
388
|
+
color: var(--ag-success-text);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
:host([variant="warning"]) button:disabled {
|
|
392
|
+
background: var(--ag-warning-background);
|
|
393
|
+
color: var(--ag-warning-text);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
:host([variant="danger"]) button:disabled {
|
|
397
|
+
background: var(--ag-danger-background);
|
|
398
|
+
color: var(--ag-danger-text);
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
:host([variant="secondary"]) button:disabled,
|
|
378
402
|
button:disabled {
|
|
379
|
-
cursor: not-allowed;
|
|
380
403
|
background: var(--ag-background-disabled);
|
|
404
|
+
color: var(--ag-text-tertiary);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
:host([variant="monochrome"]) button:disabled {
|
|
408
|
+
background: var(--ag-background-tertiary);
|
|
409
|
+
color: var(--ag-text-tertiary);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
/* Bordered buttons - dim the border and text with opacity */
|
|
413
|
+
:host([bordered]) button:disabled {
|
|
414
|
+
opacity: 60%;
|
|
415
|
+
background: transparent;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/* Ghost and link buttons - dim with opacity */
|
|
419
|
+
:host([ghost]) button:disabled,
|
|
420
|
+
:host([link]) button:disabled {
|
|
421
|
+
opacity: 60%;
|
|
422
|
+
background: transparent;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
/* All disabled buttons get not-allowed cursor */
|
|
426
|
+
button:disabled {
|
|
427
|
+
cursor: not-allowed;
|
|
381
428
|
}
|
|
382
429
|
|
|
383
430
|
button:focus-visible,
|
|
@@ -1,14 +1,28 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
|
-
import { AgTimeline as AgTimelineWC, AgTimelineItem as AgTimelineItemWC
|
|
2
|
+
import { AgTimeline as AgTimelineWC, AgTimelineItem as AgTimelineItemWC } from '../core/Timeline.js';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
declare module 'react/jsx-runtime' {
|
|
5
|
+
namespace JSX {
|
|
6
|
+
interface IntrinsicElements {
|
|
7
|
+
'ag-timeline-item': React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export interface ReactTimelineProps {
|
|
12
|
+
orientation?: 'horizontal' | 'vertical';
|
|
13
|
+
variant?: 'primary' | 'success' | 'warning' | 'danger' | 'monochrome' | '';
|
|
14
|
+
compact?: boolean;
|
|
15
|
+
ariaLabel?: string;
|
|
16
|
+
responsive?: boolean;
|
|
9
17
|
children?: React.ReactNode;
|
|
10
|
-
}
|
|
11
|
-
export
|
|
18
|
+
}
|
|
19
|
+
export declare const ReactTimeline: import('@lit/react').ReactWebComponent<AgTimelineWC, {}>;
|
|
20
|
+
export interface ReactTimelineItemProps {
|
|
21
|
+
start?: React.ReactNode;
|
|
22
|
+
marker?: React.ReactNode;
|
|
23
|
+
end?: React.ReactNode;
|
|
12
24
|
children?: React.ReactNode;
|
|
13
|
-
}
|
|
25
|
+
}
|
|
26
|
+
export declare const ReactTimelineItem: React.FC<ReactTimelineItemProps>;
|
|
27
|
+
export declare const ReactTimelineItemWC: import('@lit/react').ReactWebComponent<AgTimelineItemWC, {}>;
|
|
14
28
|
//# sourceMappingURL=ReactTimeline.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReactTimeline.d.ts","sourceRoot":"","sources":["../../../../src/components/Timeline/react/ReactTimeline.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,
|
|
1
|
+
{"version":3,"file":"ReactTimeline.d.ts","sourceRoot":"","sources":["../../../../src/components/Timeline/react/ReactTimeline.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,UAAU,IAAI,YAAY,EAAE,cAAc,IAAI,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAGrG,OAAO,QAAQ,mBAAmB,CAAC;IACjC,UAAU,GAAG,CAAC;QACZ,UAAU,iBAAiB;YACzB,kBAAkB,EAAE,KAAK,CAAC,iBAAiB,CAAC,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC,CAAC;SAC7F;KACF;CACF;AAGD,MAAM,WAAW,kBAAkB;IACjC,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;IACxC,OAAO,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,YAAY,GAAG,EAAE,CAAC;IAC3E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAGD,eAAO,MAAM,aAAa,0DAIxB,CAAC;AAGH,MAAM,WAAW,sBAAsB;IACrC,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,GAAG,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACtB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAGD,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAS9D,CAAC;AAGF,eAAO,MAAM,mBAAmB,8DAI9B,CAAC"}
|
|
@@ -1,20 +1,24 @@
|
|
|
1
|
-
import e from "
|
|
2
|
-
import
|
|
1
|
+
import { j as e } from "../../../jsx-runtime-BzflLqGi.js";
|
|
2
|
+
import a from "react";
|
|
3
|
+
import { o as l } from "../../../create-component-BPMDMe-q.js";
|
|
3
4
|
import "../core/Timeline.js";
|
|
4
|
-
import { AgTimeline as
|
|
5
|
-
const
|
|
5
|
+
import { AgTimeline as r, AgTimelineItem as o } from "../core/_Timeline.js";
|
|
6
|
+
const x = l({
|
|
6
7
|
tagName: "ag-timeline",
|
|
7
|
-
elementClass:
|
|
8
|
-
react:
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
12
|
-
|
|
8
|
+
elementClass: r,
|
|
9
|
+
react: a
|
|
10
|
+
}), j = ({ start: t, marker: i, end: m, children: n }) => /* @__PURE__ */ e.jsxs("ag-timeline-item", { children: [
|
|
11
|
+
t && /* @__PURE__ */ e.jsx("div", { slot: "ag-start", children: t }),
|
|
12
|
+
i && /* @__PURE__ */ e.jsx("div", { slot: "ag-marker", children: i }),
|
|
13
|
+
m && /* @__PURE__ */ e.jsx("div", { slot: "ag-end", children: m }),
|
|
14
|
+
n
|
|
15
|
+
] }), f = l({
|
|
13
16
|
tagName: "ag-timeline-item",
|
|
14
|
-
elementClass:
|
|
15
|
-
react:
|
|
17
|
+
elementClass: o,
|
|
18
|
+
react: a
|
|
16
19
|
});
|
|
17
20
|
export {
|
|
18
|
-
|
|
19
|
-
|
|
21
|
+
x as ReactTimeline,
|
|
22
|
+
j as ReactTimelineItem,
|
|
23
|
+
f as ReactTimelineItemWC
|
|
20
24
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agnosticui-core",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.esm.js",
|
|
@@ -449,18 +449,6 @@
|
|
|
449
449
|
"types": "./dist/components/Image/vue/index.d.ts",
|
|
450
450
|
"import": "./dist/components/Image/vue/index.js"
|
|
451
451
|
},
|
|
452
|
-
"./table": {
|
|
453
|
-
"types": "./dist/components/Table/core/_Table.d.ts",
|
|
454
|
-
"import": "./dist/components/Table/core/_Table.js"
|
|
455
|
-
},
|
|
456
|
-
"./table/react": {
|
|
457
|
-
"types": "./dist/components/Table/react/ReactTable.d.ts",
|
|
458
|
-
"import": "./dist/components/Table/react/ReactTable.js"
|
|
459
|
-
},
|
|
460
|
-
"./table/vue": {
|
|
461
|
-
"types": "./dist/components/Table/vue/index.d.ts",
|
|
462
|
-
"import": "./dist/components/Table/vue/index.js"
|
|
463
|
-
},
|
|
464
452
|
"./close-button": {
|
|
465
453
|
"types": "./dist/components/shared/CloseButton/_CloseButton.d.ts",
|
|
466
454
|
"import": "./dist/components/shared/CloseButton/_CloseButton.js"
|
|
@@ -372,9 +372,56 @@ export class AgButton extends LitElement implements ButtonProps {
|
|
|
372
372
|
background: var(--ag-background-secondary);
|
|
373
373
|
}
|
|
374
374
|
|
|
375
|
+
/* Disabled states - per-variant to maintain tonal identity */
|
|
376
|
+
|
|
377
|
+
/* Filled buttons - use lighter background tokens */
|
|
378
|
+
:host([variant="primary"]) button:disabled {
|
|
379
|
+
background: var(--ag-primary-background);
|
|
380
|
+
color: var(--ag-primary-text);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
:host([variant="success"]) button:disabled {
|
|
384
|
+
background: var(--ag-success-background);
|
|
385
|
+
color: var(--ag-success-text);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
:host([variant="warning"]) button:disabled {
|
|
389
|
+
background: var(--ag-warning-background);
|
|
390
|
+
color: var(--ag-warning-text);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
:host([variant="danger"]) button:disabled {
|
|
394
|
+
background: var(--ag-danger-background);
|
|
395
|
+
color: var(--ag-danger-text);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
:host([variant="secondary"]) button:disabled,
|
|
375
399
|
button:disabled {
|
|
376
|
-
cursor: not-allowed;
|
|
377
400
|
background: var(--ag-background-disabled);
|
|
401
|
+
color: var(--ag-text-tertiary);
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
:host([variant="monochrome"]) button:disabled {
|
|
405
|
+
background: var(--ag-background-tertiary);
|
|
406
|
+
color: var(--ag-text-tertiary);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/* Bordered buttons - dim the border and text with opacity */
|
|
410
|
+
:host([bordered]) button:disabled {
|
|
411
|
+
opacity: 60%;
|
|
412
|
+
background: transparent;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/* Ghost and link buttons - dim with opacity */
|
|
416
|
+
:host([ghost]) button:disabled,
|
|
417
|
+
:host([link]) button:disabled {
|
|
418
|
+
opacity: 60%;
|
|
419
|
+
background: transparent;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/* All disabled buttons get not-allowed cursor */
|
|
423
|
+
button:disabled {
|
|
424
|
+
cursor: not-allowed;
|
|
378
425
|
}
|
|
379
426
|
|
|
380
427
|
button:focus-visible,
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<div class="dialog drawer-bottom"
|
|
2
|
+
id="dialog-example"
|
|
3
|
+
aria-hidden="true"
|
|
4
|
+
aria-labelledby="drawer-end-title"
|
|
5
|
+
aria-describedby="drawer-end-description">
|
|
6
|
+
<div class="dialog-overlay"
|
|
7
|
+
data-a11y-dialog-hide></div>
|
|
8
|
+
<div class="dialog-content drawer-content drawer-slide-bottom"
|
|
9
|
+
role="document">
|
|
10
|
+
<div class="mbs16 mbe24 mis16 mie16">
|
|
11
|
+
<button data-a11y-dialog-hide
|
|
12
|
+
class="close-button close-button-large dialog-close"
|
|
13
|
+
aria-label="Close this dialog window">
|
|
14
|
+
<svg class="close"
|
|
15
|
+
viewBox="0 0 24 24"
|
|
16
|
+
aria-hidden="true">
|
|
17
|
+
<path fill="currentColor"
|
|
18
|
+
d="M.439 21.44a1.5 1.5 0 0 0 2.122 2.121l9.262-9.261a.25.25 0 0 1 .354 0l9.262 9.263a1.5 1.5 0 1 0 2.122-2.121L14.3 12.177a.25.25 0 0 1 0-.354l9.263-9.262A1.5 1.5 0 0 0 21.439.44L12.177 9.7a.25.25 0 0 1-.354 0L2.561.44A1.5 1.5 0 0 0 .439 2.561L9.7 11.823a.25.25 0 0 1 0 .354Z" />
|
|
19
|
+
</svg>
|
|
20
|
+
</button>
|
|
21
|
+
|
|
22
|
+
<h1 id="drawer-end-title">Subscribe to our newsletter</h1>
|
|
23
|
+
<p id="drawer-end-description">
|
|
24
|
+
Fill in the form below to receive our newsletter!
|
|
25
|
+
</p>
|
|
26
|
+
<form class="dialog-form-demo">
|
|
27
|
+
<label class="label"
|
|
28
|
+
for="email">Email (required)</label>
|
|
29
|
+
<input class="input input-rounded"
|
|
30
|
+
type="email"
|
|
31
|
+
name="EMAIL"
|
|
32
|
+
id="email"
|
|
33
|
+
placeholder="john.doe@gmail.com"
|
|
34
|
+
required />
|
|
35
|
+
<button class="btn btn-primary btn-rounded btn-block"
|
|
36
|
+
type="submit"
|
|
37
|
+
name="button">Sign up</button>
|
|
38
|
+
</form>
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
|
|
43
|
+
<button type="button"
|
|
44
|
+
class="btn btn-primary btn-bordered"
|
|
45
|
+
data-a11y-dialog-show="dialog-example">
|
|
46
|
+
Open drawer
|
|
47
|
+
</button>
|
|
48
|
+
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<div class="dialog drawer-end"
|
|
2
|
+
id="dialog-example"
|
|
3
|
+
aria-hidden="true"
|
|
4
|
+
aria-labelledby="drawer-end-title"
|
|
5
|
+
aria-describedby="drawer-end-description">
|
|
6
|
+
<div class="dialog-overlay"
|
|
7
|
+
data-a11y-dialog-hide></div>
|
|
8
|
+
<div class="dialog-content drawer-content drawer-slide-end"
|
|
9
|
+
role="document">
|
|
10
|
+
<div class="mbs16 mbe24 mis16 mie16">
|
|
11
|
+
<button data-a11y-dialog-hide
|
|
12
|
+
class="close-button close-button-large dialog-close"
|
|
13
|
+
aria-label="Close this dialog window">
|
|
14
|
+
<svg class="close"
|
|
15
|
+
viewBox="0 0 24 24"
|
|
16
|
+
aria-hidden="true">
|
|
17
|
+
<path fill="currentColor"
|
|
18
|
+
d="M.439 21.44a1.5 1.5 0 0 0 2.122 2.121l9.262-9.261a.25.25 0 0 1 .354 0l9.262 9.263a1.5 1.5 0 1 0 2.122-2.121L14.3 12.177a.25.25 0 0 1 0-.354l9.263-9.262A1.5 1.5 0 0 0 21.439.44L12.177 9.7a.25.25 0 0 1-.354 0L2.561.44A1.5 1.5 0 0 0 .439 2.561L9.7 11.823a.25.25 0 0 1 0 .354Z" />
|
|
19
|
+
</svg>
|
|
20
|
+
</button>
|
|
21
|
+
|
|
22
|
+
<h1 id="drawer-end-title">Subscribe to our newsletter</h1>
|
|
23
|
+
<p id="drawer-end-description">
|
|
24
|
+
Fill in the form below to receive our newsletter!
|
|
25
|
+
</p>
|
|
26
|
+
<form class="dialog-form-demo">
|
|
27
|
+
<label class="label"
|
|
28
|
+
for="email">Email (required)</label>
|
|
29
|
+
<input class="input input-rounded"
|
|
30
|
+
type="email"
|
|
31
|
+
name="EMAIL"
|
|
32
|
+
id="email"
|
|
33
|
+
placeholder="john.doe@gmail.com"
|
|
34
|
+
required />
|
|
35
|
+
<button class="btn btn-primary btn-rounded btn-block"
|
|
36
|
+
type="submit"
|
|
37
|
+
name="button">Sign up</button>
|
|
38
|
+
</form>
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
|
|
43
|
+
<button type="button"
|
|
44
|
+
class="btn btn-primary btn-bordered"
|
|
45
|
+
data-a11y-dialog-show="dialog-example">
|
|
46
|
+
Open drawer
|
|
47
|
+
</button>
|
|
48
|
+
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<div class="dialog drawer-start"
|
|
2
|
+
id="dialog-example"
|
|
3
|
+
aria-hidden="true"
|
|
4
|
+
aria-labelledby="drawer-end-title"
|
|
5
|
+
aria-describedby="drawer-end-description">
|
|
6
|
+
<div class="dialog-overlay"
|
|
7
|
+
data-a11y-dialog-hide></div>
|
|
8
|
+
<div class="dialog-content drawer-content drawer-slide-start"
|
|
9
|
+
role="document">
|
|
10
|
+
<div class="mbs16 mbe24 mis16 mie16">
|
|
11
|
+
<button data-a11y-dialog-hide
|
|
12
|
+
class="close-button close-button-large dialog-close"
|
|
13
|
+
aria-label="Close this dialog window">
|
|
14
|
+
<svg class="close"
|
|
15
|
+
viewBox="0 0 24 24"
|
|
16
|
+
aria-hidden="true">
|
|
17
|
+
<path fill="currentColor"
|
|
18
|
+
d="M.439 21.44a1.5 1.5 0 0 0 2.122 2.121l9.262-9.261a.25.25 0 0 1 .354 0l9.262 9.263a1.5 1.5 0 1 0 2.122-2.121L14.3 12.177a.25.25 0 0 1 0-.354l9.263-9.262A1.5 1.5 0 0 0 21.439.44L12.177 9.7a.25.25 0 0 1-.354 0L2.561.44A1.5 1.5 0 0 0 .439 2.561L9.7 11.823a.25.25 0 0 1 0 .354Z" />
|
|
19
|
+
</svg>
|
|
20
|
+
</button>
|
|
21
|
+
|
|
22
|
+
<h1 id="drawer-end-title">Subscribe to our newsletter</h1>
|
|
23
|
+
<p id="drawer-end-description">
|
|
24
|
+
Fill in the form below to receive our newsletter!
|
|
25
|
+
</p>
|
|
26
|
+
<form class="dialog-form-demo">
|
|
27
|
+
<label class="label"
|
|
28
|
+
for="email">Email (required)</label>
|
|
29
|
+
<input class="input input-rounded"
|
|
30
|
+
type="email"
|
|
31
|
+
name="EMAIL"
|
|
32
|
+
id="email"
|
|
33
|
+
placeholder="john.doe@gmail.com"
|
|
34
|
+
required />
|
|
35
|
+
<button class="btn btn-primary btn-rounded btn-block"
|
|
36
|
+
type="submit"
|
|
37
|
+
name="button">Sign up</button>
|
|
38
|
+
</form>
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
|
|
43
|
+
<button type="button"
|
|
44
|
+
class="btn btn-primary btn-bordered"
|
|
45
|
+
data-a11y-dialog-show="dialog-example">
|
|
46
|
+
Open drawer
|
|
47
|
+
</button>
|
|
48
|
+
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<div class="dialog drawer-top"
|
|
2
|
+
id="dialog-example"
|
|
3
|
+
aria-hidden="true"
|
|
4
|
+
aria-labelledby="drawer-end-title"
|
|
5
|
+
aria-describedby="drawer-end-description">
|
|
6
|
+
<div class="dialog-overlay"
|
|
7
|
+
data-a11y-dialog-hide></div>
|
|
8
|
+
<div class="dialog-content drawer-content drawer-slide-top"
|
|
9
|
+
role="document">
|
|
10
|
+
<div class="mbs16 mbe24 mis16 mie16">
|
|
11
|
+
<button data-a11y-dialog-hide
|
|
12
|
+
class="close-button close-button-large dialog-close"
|
|
13
|
+
aria-label="Close this dialog window">
|
|
14
|
+
<svg class="close"
|
|
15
|
+
viewBox="0 0 24 24"
|
|
16
|
+
aria-hidden="true">
|
|
17
|
+
<path fill="currentColor"
|
|
18
|
+
d="M.439 21.44a1.5 1.5 0 0 0 2.122 2.121l9.262-9.261a.25.25 0 0 1 .354 0l9.262 9.263a1.5 1.5 0 1 0 2.122-2.121L14.3 12.177a.25.25 0 0 1 0-.354l9.263-9.262A1.5 1.5 0 0 0 21.439.44L12.177 9.7a.25.25 0 0 1-.354 0L2.561.44A1.5 1.5 0 0 0 .439 2.561L9.7 11.823a.25.25 0 0 1 0 .354Z" />
|
|
19
|
+
</svg>
|
|
20
|
+
</button>
|
|
21
|
+
|
|
22
|
+
<h1 id="drawer-end-title">Subscribe to our newsletter</h1>
|
|
23
|
+
<p id="drawer-end-description">
|
|
24
|
+
Fill in the form below to receive our newsletter!
|
|
25
|
+
</p>
|
|
26
|
+
<form class="dialog-form-demo">
|
|
27
|
+
<label class="label"
|
|
28
|
+
for="email">Email (required)</label>
|
|
29
|
+
<input class="input input-rounded"
|
|
30
|
+
type="email"
|
|
31
|
+
name="EMAIL"
|
|
32
|
+
id="email"
|
|
33
|
+
placeholder="john.doe@gmail.com"
|
|
34
|
+
required />
|
|
35
|
+
<button class="btn btn-primary btn-rounded btn-block"
|
|
36
|
+
type="submit"
|
|
37
|
+
name="button">Sign up</button>
|
|
38
|
+
</form>
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
|
|
43
|
+
<button type="button"
|
|
44
|
+
class="btn btn-primary btn-bordered"
|
|
45
|
+
data-a11y-dialog-show="dialog-example">
|
|
46
|
+
Open drawer
|
|
47
|
+
</button>
|
|
48
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
.dialog h1 {
|
|
2
|
+
margin: 0;
|
|
3
|
+
|
|
4
|
+
/* Since this is in a modal we want to force it smaller */
|
|
5
|
+
font-size: var(--agnostic-h3);
|
|
6
|
+
font-weight: 400;
|
|
7
|
+
line-height: 1;
|
|
8
|
+
margin-block-end: var(--fluid-16);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.dialog-form-demo > input {
|
|
12
|
+
margin-block-end: var(--fluid-24);
|
|
13
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
title: Dialog
|
|
2
|
+
notes: |
|
|
3
|
+
Dialog is a base-level implementation of a dialog component that can/will be leveraged for other components like popover, modal, menu, etc. Currently, the demo here is utilizing Kitty Giraudel's [a11y-dialog](https://github.com/KittyGiraudel/a11y-dialog) which is a very clean styling-agnostic JavaScript implementation that supports what you'd expect from an a11y-compliant dialog and has saved me a lot of time while I figure out the styles. Thus, the structure should be consistent with what `a11y-dialog` recommends in terms of markup structure. The `a11y-dialog` script is currently pulled in via CDN.
|
|
4
|
+
|
|
5
|
+
To be absolutely 100% clear, if you utilize AgnosticUI's CSS package, you only get the HTML/CSS for dialog. The functionality in terms of showing / dismissing the dialog, navigating with your keyboard, etc., is being handled by [a11y-dialog](https://github.com/KittyGiraudel/a11y-dialog). The AgnosticUI framework implementations (React, Angular, Svelte, Vue, etc.) likely WILL handle said functionality once they've been implemented (not the case at time of writing).
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
.dialog,
|
|
2
|
+
.dialog-overlay {
|
|
3
|
+
position: fixed;
|
|
4
|
+
top: 0;
|
|
5
|
+
right: 0;
|
|
6
|
+
bottom: 0;
|
|
7
|
+
left: 0;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.dialog {
|
|
11
|
+
z-index: 1001;
|
|
12
|
+
display: flex;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.dialog[aria-hidden="true"] {
|
|
16
|
+
display: none;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.dialog-overlay {
|
|
20
|
+
background-color: rgb(50 50 50 / 60%);
|
|
21
|
+
animation: fade-in var(--agnostic-timing-fast) both;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.dialog-content {
|
|
25
|
+
background-color: var(--agnostic-light);
|
|
26
|
+
margin: auto;
|
|
27
|
+
z-index: 1001;
|
|
28
|
+
position: relative;
|
|
29
|
+
padding: var(--fluid-16);
|
|
30
|
+
max-width: 90%;
|
|
31
|
+
width: 600px;
|
|
32
|
+
border-radius: var(--agnostic-radius);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.dialog-fade-in {
|
|
36
|
+
animation: fade-in var(--agnostic-timing-fast) both;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.dialog-slide-up {
|
|
40
|
+
animation: slide-up var(--agnostic-timing-slow) var(--agnostic-timing-fast) both;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Cannot use two separate CSS classes with animation: foo, bar
|
|
45
|
+
* as the later class will overwrite the first (so this combines)
|
|
46
|
+
*/
|
|
47
|
+
.dialog-slide-up-fade-in {
|
|
48
|
+
animation:
|
|
49
|
+
fade-in var(--agnostic-timing-fast) both,
|
|
50
|
+
slide-up var(--agnostic-timing-slow) var(--agnostic-timing-fast) both;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
@media screen and (min-width: 700px) {
|
|
54
|
+
.dialog-content {
|
|
55
|
+
padding: var(--fluid-32);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
@keyframes fade-in {
|
|
60
|
+
from {
|
|
61
|
+
opacity: 0%;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
@keyframes slide-up {
|
|
66
|
+
from {
|
|
67
|
+
transform: translateY(10%);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/* Shared with AgnosticUI close buton so only need positioning and transition */
|
|
72
|
+
.dialog-close {
|
|
73
|
+
position: absolute;
|
|
74
|
+
top: var(--fluid-8);
|
|
75
|
+
right: var(--fluid-8);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
@media (prefers-reduced-motion), (update: slow) {
|
|
79
|
+
.dialog-slide-up-fade-in,
|
|
80
|
+
.dialog-fade-in,
|
|
81
|
+
.dialog-slide-up,
|
|
82
|
+
.dialog-content {
|
|
83
|
+
transition-duration: 0.001ms !important;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
@media only screen and (min-width: 576px) {
|
|
88
|
+
.dialog-close {
|
|
89
|
+
top: var(--fluid-12);
|
|
90
|
+
right: var(--fluid-12);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
@media screen and (min-width: 768px) {
|
|
95
|
+
.dialog-close {
|
|
96
|
+
top: var(--fluid-16);
|
|
97
|
+
right: var(--fluid-16);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<div class="dialog"
|
|
2
|
+
id="dialog-example"
|
|
3
|
+
aria-hidden="true"
|
|
4
|
+
aria-labelledby="dialog-example-title"
|
|
5
|
+
aria-describedby="dialog-example-description">
|
|
6
|
+
<div class="dialog-overlay"
|
|
7
|
+
data-a11y-dialog-hide></div>
|
|
8
|
+
<div class="dialog-content"
|
|
9
|
+
role="document">
|
|
10
|
+
<div class="mbs16 mbe24 mis16 mie16">
|
|
11
|
+
<button data-a11y-dialog-hide
|
|
12
|
+
class="close-button close-button-large dialog-close"
|
|
13
|
+
aria-label="Close this dialog window">
|
|
14
|
+
<svg class="close"
|
|
15
|
+
viewBox="0 0 24 24"
|
|
16
|
+
aria-hidden="true">
|
|
17
|
+
<path fill="currentColor"
|
|
18
|
+
d="M.439 21.44a1.5 1.5 0 0 0 2.122 2.121l9.262-9.261a.25.25 0 0 1 .354 0l9.262 9.263a1.5 1.5 0 1 0 2.122-2.121L14.3 12.177a.25.25 0 0 1 0-.354l9.263-9.262A1.5 1.5 0 0 0 21.439.44L12.177 9.7a.25.25 0 0 1-.354 0L2.561.44A1.5 1.5 0 0 0 .439 2.561L9.7 11.823a.25.25 0 0 1 0 .354Z" />
|
|
19
|
+
</svg>
|
|
20
|
+
</button>
|
|
21
|
+
|
|
22
|
+
<h1 id="dialog-example-title">Subscribe to our newsletter</h1>
|
|
23
|
+
<p id="dialog-example-description">
|
|
24
|
+
Fill in the form below to receive our newsletter!
|
|
25
|
+
</p>
|
|
26
|
+
<form class="dialog-form-demo">
|
|
27
|
+
<label class="label"
|
|
28
|
+
for="email">Email (required)</label>
|
|
29
|
+
<input class="input input-rounded"
|
|
30
|
+
type="email"
|
|
31
|
+
name="EMAIL"
|
|
32
|
+
id="email"
|
|
33
|
+
placeholder="john.doe@gmail.com"
|
|
34
|
+
required />
|
|
35
|
+
<button class="btn btn-primary btn-rounded btn-block"
|
|
36
|
+
type="submit"
|
|
37
|
+
name="button">Sign up</button>
|
|
38
|
+
</form>
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
|
|
43
|
+
<button type="button"
|
|
44
|
+
class="btn btn-primary btn-bordered"
|
|
45
|
+
data-a11y-dialog-show="dialog-example">
|
|
46
|
+
Open the dialog
|
|
47
|
+
</button>
|
|
48
|
+
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Place these alongside the content like:
|
|
3
|
+
* <div class="dialog-content drawer-content drawer-slide-start"...
|
|
4
|
+
*/
|
|
5
|
+
.drawer-slide-start {
|
|
6
|
+
animation: slide-start var(--agnostic-timing-fast) ease-in-out;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.drawer-slide-end {
|
|
10
|
+
animation: slide-end var(--agnostic-timing-fast) ease-in-out;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.drawer-slide-bottom {
|
|
14
|
+
animation: slide-bottom var(--agnostic-timing-fast) ease-in-out;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.drawer-slide-top {
|
|
18
|
+
animation: slide-top var(--agnostic-timing-fast) ease-in-out;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
@keyframes slide-top {
|
|
22
|
+
from {
|
|
23
|
+
transform: translateY(-100%);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
@keyframes slide-bottom {
|
|
28
|
+
from {
|
|
29
|
+
transform: translateY(100%);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
@keyframes slide-start {
|
|
34
|
+
from {
|
|
35
|
+
transform: translateX(-100%);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@keyframes slide-end {
|
|
40
|
+
from {
|
|
41
|
+
transform: translateX(100%);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@media (prefers-reduced-motion), (update: slow) {
|
|
46
|
+
.drawer-slide-top,
|
|
47
|
+
.drawer-slide-bottom,
|
|
48
|
+
.drawer-slide-start,
|
|
49
|
+
.drawer-slide-end {
|
|
50
|
+
transition-duration: 0.001ms !important;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
.drawer-start {
|
|
2
|
+
right: initial;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.drawer-start[aria-hidden] {
|
|
6
|
+
transform: none;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.drawer-end {
|
|
10
|
+
left: initial;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.drawer-end[aria-hidden] {
|
|
14
|
+
transform: none;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.drawer-top {
|
|
18
|
+
bottom: initial;
|
|
19
|
+
transform: none;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.drawer-top[aria-hidden] {
|
|
23
|
+
transform: none;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.drawer-bottom {
|
|
27
|
+
top: initial;
|
|
28
|
+
transform: none;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.drawer-bottom[aria-hidden] {
|
|
32
|
+
transform: none;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.drawer-content {
|
|
36
|
+
margin: initial;
|
|
37
|
+
max-width: initial;
|
|
38
|
+
border-radius: initial;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.drawer-start .drawer-content,
|
|
42
|
+
.drawer-end .drawer-content {
|
|
43
|
+
width: 25rem;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.drawer-top .drawer-content,
|
|
47
|
+
.drawer-bottom .drawer-content {
|
|
48
|
+
height: 25vh;
|
|
49
|
+
width: 100%;
|
|
50
|
+
}
|
|
@@ -1,34 +1,57 @@
|
|
|
1
|
-
// v2/lib/src/components/Timeline/react/
|
|
2
|
-
import React from
|
|
3
|
-
import { createComponent } from
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
// v2/lib/src/components/Timeline/react/ReactTimeline.tsx
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { createComponent } from '@lit/react';
|
|
4
|
+
import { AgTimeline as AgTimelineWC, AgTimelineItem as AgTimelineItemWC } from '../core/Timeline.js';
|
|
5
|
+
|
|
6
|
+
// Extend React JSX IntrinsicElements to include custom timeline elements
|
|
7
|
+
declare module 'react/jsx-runtime' {
|
|
8
|
+
namespace JSX {
|
|
9
|
+
interface IntrinsicElements {
|
|
10
|
+
'ag-timeline-item': React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Define the props for the Timeline component
|
|
16
|
+
export interface ReactTimelineProps {
|
|
17
|
+
orientation?: 'horizontal' | 'vertical';
|
|
18
|
+
variant?: 'primary' | 'success' | 'warning' | 'danger' | 'monochrome' | '';
|
|
19
|
+
compact?: boolean;
|
|
20
|
+
ariaLabel?: string;
|
|
21
|
+
responsive?: boolean;
|
|
22
|
+
children?: React.ReactNode;
|
|
23
|
+
}
|
|
9
24
|
|
|
10
25
|
// Create React wrapper for Timeline
|
|
11
26
|
export const ReactTimeline = createComponent({
|
|
12
|
-
tagName:
|
|
27
|
+
tagName: 'ag-timeline',
|
|
13
28
|
elementClass: AgTimelineWC,
|
|
14
29
|
react: React,
|
|
15
|
-
events: {
|
|
16
|
-
onSlotChange: "slotchange",
|
|
17
|
-
},
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
// Create React wrapper for TimelineItem
|
|
21
|
-
export const ReactTimelineItem = createComponent({
|
|
22
|
-
tagName: "ag-timeline-item",
|
|
23
|
-
elementClass: AgTimelineItemWC,
|
|
24
|
-
react: React,
|
|
25
30
|
});
|
|
26
31
|
|
|
27
|
-
//
|
|
28
|
-
export
|
|
32
|
+
// Define the props for the TimelineItem component
|
|
33
|
+
export interface ReactTimelineItemProps {
|
|
34
|
+
start?: React.ReactNode;
|
|
35
|
+
marker?: React.ReactNode;
|
|
36
|
+
end?: React.ReactNode;
|
|
29
37
|
children?: React.ReactNode;
|
|
30
|
-
}
|
|
38
|
+
}
|
|
31
39
|
|
|
32
|
-
|
|
33
|
-
|
|
40
|
+
// Custom TimelineItem to handle slots as props
|
|
41
|
+
export const ReactTimelineItem: React.FC<ReactTimelineItemProps> = ({ start, marker, end, children }) => {
|
|
42
|
+
return (
|
|
43
|
+
<ag-timeline-item>
|
|
44
|
+
{start && <div slot="ag-start">{start}</div>}
|
|
45
|
+
{marker && <div slot="ag-marker">{marker}</div>}
|
|
46
|
+
{end && <div slot="ag-end">{end}</div>}
|
|
47
|
+
{children}
|
|
48
|
+
</ag-timeline-item>
|
|
49
|
+
);
|
|
34
50
|
};
|
|
51
|
+
|
|
52
|
+
// Original TimelineItem wrapper (if needed for other purposes)
|
|
53
|
+
export const ReactTimelineItemWC = createComponent({
|
|
54
|
+
tagName: 'ag-timeline-item',
|
|
55
|
+
elementClass: AgTimelineItemWC,
|
|
56
|
+
react: React,
|
|
57
|
+
});
|
package/src/styles/ag-tokens.css
CHANGED
|
@@ -1,295 +0,0 @@
|
|
|
1
|
-
# RTL Support Implementation Plan - AgnosticUI v2
|
|
2
|
-
|
|
3
|
-
## Goal
|
|
4
|
-
Convert all directional CSS properties to logical properties to support RTL (Right-to-Left) languages without breaking existing functionality.
|
|
5
|
-
|
|
6
|
-
## Overview
|
|
7
|
-
This is primarily a search-and-replace task to convert directional properties (left/right) to logical properties (inline-start/inline-end). However, there are edge cases that need careful handling.
|
|
8
|
-
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
## Implementation Steps
|
|
12
|
-
|
|
13
|
-
### Step 1: Convert Spacing Properties (Margin & Padding) ✅ COMPLETED
|
|
14
|
-
**Scope:** 17 occurrences in main library (`v2/lib/src/`) - all converted
|
|
15
|
-
|
|
16
|
-
**Search & Replace:**
|
|
17
|
-
- `margin-left:` → `margin-inline-start:`
|
|
18
|
-
- `margin-right:` → `margin-inline-end:`
|
|
19
|
-
- `padding-left:` → `padding-inline-start:`
|
|
20
|
-
- `padding-right:` → `padding-inline-end:`
|
|
21
|
-
|
|
22
|
-
**Priority Files:**
|
|
23
|
-
- AspectRatio component
|
|
24
|
-
- Loader component
|
|
25
|
-
- SidebarNav component
|
|
26
|
-
- Input component (backup file)
|
|
27
|
-
- Checkbox component (mixed usage)
|
|
28
|
-
- Pagination component (mixed usage)
|
|
29
|
-
|
|
30
|
-
**Gotchas:**
|
|
31
|
-
- None - these are safe to replace
|
|
32
|
-
|
|
33
|
-
---
|
|
34
|
-
|
|
35
|
-
### Step 2: Convert Border Properties ✅ COMPLETED
|
|
36
|
-
**Scope:** 56 occurrences in main library (`v2/lib/src/`) - all converted (42 borders + 14 border-radius)
|
|
37
|
-
|
|
38
|
-
**Search & Replace:**
|
|
39
|
-
- `border-left:` → `border-inline-start:`
|
|
40
|
-
- `border-right:` → `border-inline-end:`
|
|
41
|
-
- `border-left-width:` → `border-inline-start-width:`
|
|
42
|
-
- `border-right-width:` → `border-inline-end-width:`
|
|
43
|
-
- `border-left-color:` → `border-inline-start-color:`
|
|
44
|
-
- `border-right-color:` → `border-inline-end-color:`
|
|
45
|
-
- `border-left-style:` → `border-inline-start-style:`
|
|
46
|
-
- `border-right-style:` → `border-inline-end-style:`
|
|
47
|
-
|
|
48
|
-
**Priority Files:**
|
|
49
|
-
- Alert component (`border-left-width`, `border-left-color`)
|
|
50
|
-
- Combobox component (`border-right-color`, `border-right`)
|
|
51
|
-
|
|
52
|
-
**Gotchas:**
|
|
53
|
-
- Border radius properties (if any) need special handling:
|
|
54
|
-
- `border-top-left-radius` → `border-start-start-radius`
|
|
55
|
-
- `border-top-right-radius` → `border-start-end-radius`
|
|
56
|
-
- `border-bottom-left-radius` → `border-end-start-radius`
|
|
57
|
-
- `border-bottom-right-radius` → `border-end-end-radius`
|
|
58
|
-
|
|
59
|
-
---
|
|
60
|
-
|
|
61
|
-
### Step 3: Convert Text Alignment ✅ COMPLETED
|
|
62
|
-
**Scope:** 7 occurrences in main library (`v2/lib/src/`) - all converted
|
|
63
|
-
|
|
64
|
-
**Search & Replace:**
|
|
65
|
-
- `text-align: left` → `text-align: start`
|
|
66
|
-
- `text-align: right` → `text-align: end`
|
|
67
|
-
|
|
68
|
-
**Priority Files:**
|
|
69
|
-
- Table component (v2/lib/src/styles/table.css:16, 24, 180, 192)
|
|
70
|
-
|
|
71
|
-
**Gotchas:**
|
|
72
|
-
- `text-align: center` stays as-is
|
|
73
|
-
- Double-check that `start`/`end` work in your target browser support matrix (modern browsers only)
|
|
74
|
-
|
|
75
|
-
---
|
|
76
|
-
|
|
77
|
-
### Step 4: Convert Positioning Properties ✅
|
|
78
|
-
|
|
79
|
-
**Scope:** ~50+ occurrences across 15+ files
|
|
80
|
-
|
|
81
|
-
**Search & Replace:**
|
|
82
|
-
- `left:` → `inset-inline-start:`
|
|
83
|
-
- `right:` → `inset-inline-end:`
|
|
84
|
-
- `left: 0; right: 0;` → `inset-inline: 0;`
|
|
85
|
-
- `top: 0; left: 0; right: 0; bottom: 0;` → `inset: 0;`
|
|
86
|
-
|
|
87
|
-
**Files Converted:**
|
|
88
|
-
- table.css, positioning.ts (utility)
|
|
89
|
-
- BadgeFx, SkeletonLoader, ScrollProgress, Dialog
|
|
90
|
-
- Sidebar, ScrollToButton, CloseButton
|
|
91
|
-
- MessageBubble, Toggle, Loader, ButtonFx
|
|
92
|
-
- Menu, Slider, Combobox
|
|
93
|
-
- Toast, Checkbox
|
|
94
|
-
|
|
95
|
-
**Gotchas:**
|
|
96
|
-
- **CRITICAL**: Only for `position: absolute`, `position: fixed`, or `position: sticky` elements
|
|
97
|
-
- Check for instances where `left: 0; right: 0;` is used together (might be better as `inset-inline: 0;`)
|
|
98
|
-
- Do NOT convert `left`/`right` in transform functions (see Step 5)
|
|
99
|
-
|
|
100
|
-
**Manual Review Needed:**
|
|
101
|
-
- Search for `position: absolute` and check nearby `left`/`right` properties
|
|
102
|
-
- Search for `position: fixed` and check nearby `left`/`right` properties
|
|
103
|
-
|
|
104
|
-
---
|
|
105
|
-
|
|
106
|
-
### Step 5: Handle Transforms & Animations ✅
|
|
107
|
-
|
|
108
|
-
**Scope:** Reviewed all `translateX` usage, added RTL support to 5 components with directional animations
|
|
109
|
-
|
|
110
|
-
**Components with RTL Support Added:**
|
|
111
|
-
- **positioning.ts** - Utility for drawer start/end slide animations
|
|
112
|
-
- **Dialog** - Drawer mode start/end positioning
|
|
113
|
-
- **Toast** - Start/end position slide animations
|
|
114
|
-
- **Toggle** - Handle movement (checked state)
|
|
115
|
-
- **ButtonFx** - Side-slide hover effect
|
|
116
|
-
|
|
117
|
-
**Components Skipped (decorative/centering only):**
|
|
118
|
-
- Sidebar - Already has RTL support ✓
|
|
119
|
-
- Slider - Uses `translateX(-50%)` for centering only
|
|
120
|
-
- BadgeFx, SkeletonLoader - Shimmer effects (decorative)
|
|
121
|
-
- motion.styles.ts - Shake and highlight-sweep animations (decorative)
|
|
122
|
-
|
|
123
|
-
**Pattern Used:**
|
|
124
|
-
All RTL overrides follow the Sidebar pattern using `:host-context([dir="rtl"])`:
|
|
125
|
-
```css
|
|
126
|
-
/* LTR (default) */
|
|
127
|
-
.element {
|
|
128
|
-
transform: translateX(-100%);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/* RTL override */
|
|
132
|
-
:host-context([dir="rtl"]) .element {
|
|
133
|
-
transform: translateX(100%);
|
|
134
|
-
}
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
**Gotchas:**
|
|
138
|
-
- Cannot simply replace `translateX` with a logical property
|
|
139
|
-
- Requires `:host-context([dir="rtl"])` or `[dir="rtl"]` selectors for overrides
|
|
140
|
-
- Only directional animations need RTL support; centering and decorative effects don't
|
|
141
|
-
|
|
142
|
-
---
|
|
143
|
-
|
|
144
|
-
### Step 6: Convert Size Properties (Width & Height)
|
|
145
|
-
|
|
146
|
-
**Scope:** ~74 CSS property occurrences (excluding media queries, docs, and tests)
|
|
147
|
-
|
|
148
|
-
**Search & Replace:**
|
|
149
|
-
- `min-width:` → `min-inline-size:`
|
|
150
|
-
- `max-width:` → `max-inline-size:`
|
|
151
|
-
- `min-height:` → `min-block-size:`
|
|
152
|
-
- `max-height:` → `max-block-size:`
|
|
153
|
-
|
|
154
|
-
**CRITICAL Gotcha - Media Queries:**
|
|
155
|
-
Logical properties do NOT work in media queries yet. You CANNOT replace:
|
|
156
|
-
- `@media (min-width: 640px)` - Must stay as-is ❌
|
|
157
|
-
- `@media (max-width: 1024px)` - Must stay as-is ❌
|
|
158
|
-
|
|
159
|
-
Only replace size properties in CSS property declarations:
|
|
160
|
-
```css
|
|
161
|
-
/* ✅ CAN REPLACE */
|
|
162
|
-
.element {
|
|
163
|
-
min-width: 200px; → min-inline-size: 200px;
|
|
164
|
-
max-width: 100%; → max-inline-size: 100%;
|
|
165
|
-
min-height: 100px; → min-block-size: 100px;
|
|
166
|
-
max-height: 90vh; → max-block-size: 90vh;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/* ❌ CANNOT REPLACE */
|
|
170
|
-
@media (min-width: 640px) { → Leave as-is!
|
|
171
|
-
/* styles */
|
|
172
|
-
}
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
**Action:**
|
|
176
|
-
1. Search for `min-width:`, `max-width:`, `min-height:`, `max-height:` in CSS property declarations
|
|
177
|
-
2. Verify each occurrence is NOT in a media query
|
|
178
|
-
3. Replace with logical equivalent
|
|
179
|
-
4. Skip .md, .spec.ts, and demo files (documentation/tests)
|
|
180
|
-
|
|
181
|
-
**Priority Files:**
|
|
182
|
-
- form-control-styles.ts (4 occurrences)
|
|
183
|
-
- positioning.ts (4 occurrences)
|
|
184
|
-
- Popover, Dialog, Toast, Combobox components
|
|
185
|
-
- Button, Icon, IconButton components
|
|
186
|
-
- Many other components (~30 files total)
|
|
187
|
-
|
|
188
|
-
**Gotchas:**
|
|
189
|
-
- Media queries MUST stay as physical properties (min-width/max-width)
|
|
190
|
-
- Only convert actual CSS property declarations
|
|
191
|
-
- Watch for dynamically generated styles in TypeScript/JavaScript
|
|
192
|
-
|
|
193
|
-
---
|
|
194
|
-
|
|
195
|
-
### Step 7: Update Class Names (Semantic Cleanup)
|
|
196
|
-
|
|
197
|
-
**Optional but Recommended:**
|
|
198
|
-
Update class names to be semantically correct:
|
|
199
|
-
- `.alert-border-left` → `.alert-border-start`
|
|
200
|
-
- `.margin-left-*` → `.margin-inline-start-*`
|
|
201
|
-
- Any other directional class names
|
|
202
|
-
|
|
203
|
-
**Action:**
|
|
204
|
-
- Search for class names containing "left" or "right"
|
|
205
|
-
- Rename to "start" or "end" where appropriate
|
|
206
|
-
- Update corresponding CSS and component usage
|
|
207
|
-
|
|
208
|
-
**Gotchas:**
|
|
209
|
-
- This is a breaking change if classes are exposed as public API
|
|
210
|
-
- Consider deprecation strategy if needed
|
|
211
|
-
|
|
212
|
-
---
|
|
213
|
-
|
|
214
|
-
### Step 8: Test RTL Rendering
|
|
215
|
-
|
|
216
|
-
**Action:**
|
|
217
|
-
1. Create test HTML files with `dir="rtl"` attribute
|
|
218
|
-
2. Visually test critical components:
|
|
219
|
-
- Alert (border should appear on the right in RTL)
|
|
220
|
-
- Table (text alignment should flip)
|
|
221
|
-
- Combobox (borders should flip)
|
|
222
|
-
- Form controls (labels should flip with start/end positioning)
|
|
223
|
-
- Sidebar (should slide from correct direction)
|
|
224
|
-
3. Run existing test suite to ensure no regressions
|
|
225
|
-
|
|
226
|
-
**Test Checklist:**
|
|
227
|
-
- [ ] Alert component border appears on correct side in RTL
|
|
228
|
-
- [ ] Table text aligns correctly in RTL
|
|
229
|
-
- [ ] Form controls with `labelPosition="start"` appear on right side in RTL
|
|
230
|
-
- [ ] Form controls with `labelPosition="end"` appear on left side in RTL
|
|
231
|
-
- [ ] Sidebar animations work correctly in RTL
|
|
232
|
-
- [ ] No visual regressions in LTR mode
|
|
233
|
-
|
|
234
|
-
---
|
|
235
|
-
|
|
236
|
-
## Execution Strategy
|
|
237
|
-
|
|
238
|
-
### Recommended Approach
|
|
239
|
-
1. Start with Steps 1-3 (spacing, borders, text-align) - these are safest
|
|
240
|
-
2. Do Step 4 (positioning) with manual review of each file
|
|
241
|
-
3. Do Step 5 (transforms) with careful testing
|
|
242
|
-
4. Do Step 6 (size properties) - safe but watch for media queries
|
|
243
|
-
5. Optionally do Step 7 (class names) if you want semantic correctness
|
|
244
|
-
6. Do Step 8 (testing) throughout the process
|
|
245
|
-
|
|
246
|
-
### Automation
|
|
247
|
-
You can use global find-and-replace for Steps 1-3, but recommend:
|
|
248
|
-
- Do it file-by-file or component-by-component
|
|
249
|
-
- Test after each component to catch issues early
|
|
250
|
-
- Commit after each component for easy rollback
|
|
251
|
-
|
|
252
|
-
### Browser Support
|
|
253
|
-
CSS logical properties are supported in:
|
|
254
|
-
- Chrome 87+
|
|
255
|
-
- Firefox 66+
|
|
256
|
-
- Safari 14.1+
|
|
257
|
-
- Edge 87+
|
|
258
|
-
|
|
259
|
-
If you need to support older browsers, you'll need fallbacks or a different strategy.
|
|
260
|
-
|
|
261
|
-
---
|
|
262
|
-
|
|
263
|
-
## Risks & Mitigations
|
|
264
|
-
|
|
265
|
-
| Risk | Mitigation |
|
|
266
|
-
|------|------------|
|
|
267
|
-
| Breaking existing layouts | Test each component after changes; commit frequently |
|
|
268
|
-
| Transform animations not flipping | Use `:host-context([dir="rtl"])` overrides (see Sidebar example) |
|
|
269
|
-
| Class name changes breaking user code | Skip Step 6, or provide deprecation warning |
|
|
270
|
-
| Browser compatibility | Check caniuse.com for logical properties support |
|
|
271
|
-
|
|
272
|
-
---
|
|
273
|
-
|
|
274
|
-
## Estimated Effort
|
|
275
|
-
|
|
276
|
-
- Step 1 (spacing): 1-2 hours (bulk search-replace + testing) ✅ COMPLETED
|
|
277
|
-
- Step 2 (borders): 30 minutes
|
|
278
|
-
- Step 3 (text-align): 15 minutes
|
|
279
|
-
- Step 4 (positioning): 1 hour (manual review needed)
|
|
280
|
-
- Step 5 (transforms): 1 hour (manual review + testing)
|
|
281
|
-
- Step 6 (size properties): 1-2 hours (careful to avoid media queries)
|
|
282
|
-
- Step 7 (class names): 1 hour (optional)
|
|
283
|
-
- Step 8 (testing): 1-2 hours
|
|
284
|
-
|
|
285
|
-
**Total: 6-10 hours** (without class name changes: 5-9 hours)
|
|
286
|
-
|
|
287
|
-
---
|
|
288
|
-
|
|
289
|
-
## Success Criteria
|
|
290
|
-
|
|
291
|
-
- [ ] All directional properties converted to logical properties
|
|
292
|
-
- [ ] All existing tests pass
|
|
293
|
-
- [ ] Visual testing with `dir="rtl"` shows correct rendering
|
|
294
|
-
- [ ] No regressions in LTR mode
|
|
295
|
-
- [ ] Components handle RTL without explicit RTL-specific code (except transforms)
|
package/dist/global.d.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import "react";
|
package/src/global.d.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
|
|
3
|
-
declare global {
|
|
4
|
-
namespace JSX {
|
|
5
|
-
interface IntrinsicElements {
|
|
6
|
-
'ag-accordion': React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
7
|
-
'ag-accordion-item': React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement> & {
|
|
8
|
-
open?: boolean;
|
|
9
|
-
'heading-level'?: number;
|
|
10
|
-
disabled?: boolean;
|
|
11
|
-
}, HTMLElement>;
|
|
12
|
-
'ag-tooltip': React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement> & {
|
|
13
|
-
content?: string;
|
|
14
|
-
placement?: string;
|
|
15
|
-
trigger?: string;
|
|
16
|
-
}, HTMLElement>;
|
|
17
|
-
'ag-menu-button': React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement> & {
|
|
18
|
-
disabled?: boolean;
|
|
19
|
-
'aria-label'?: string;
|
|
20
|
-
}, HTMLElement>;
|
|
21
|
-
'ag-menu': React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement> & {
|
|
22
|
-
open?: boolean;
|
|
23
|
-
placement?: 'bottom-start' | 'bottom-end' | 'top-start' | 'top-end';
|
|
24
|
-
'aria-label'?: string;
|
|
25
|
-
'aria-labelledby'?: string;
|
|
26
|
-
}, HTMLElement>;
|
|
27
|
-
'ag-menu-item': React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement> & {
|
|
28
|
-
value?: string;
|
|
29
|
-
disabled?: boolean;
|
|
30
|
-
href?: string;
|
|
31
|
-
target?: string;
|
|
32
|
-
}, HTMLElement>;
|
|
33
|
-
'ag-menu-separator': React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// Vue module declarations
|
|
39
|
-
declare module '*.vue' {
|
|
40
|
-
import type { DefineComponent } from 'vue';
|
|
41
|
-
const component: DefineComponent<Record<string, unknown>, Record<string, unknown>, unknown>;
|
|
42
|
-
export default component;
|
|
43
|
-
}
|