@newthink/ui 0.1.3 → 0.3.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.
@@ -0,0 +1,6 @@
1
+ import { AlpinePlugin } from '../types';
2
+ export declare const accordionGroup: AlpinePlugin;
3
+ export declare const accordion: AlpinePlugin;
4
+ export declare const accordions: AlpinePlugin;
5
+ export default accordions;
6
+ //# sourceMappingURL=accordion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accordion.d.ts","sourceRoot":"","sources":["../../src/headless/accordion.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAiDxC,eAAO,MAAM,cAAc,EAAE,YAC8B,CAAC;AAqD5D,eAAO,MAAM,SAAS,cAIrB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,YAGxB,CAAC;AACF,eAAe,UAAU,CAAC"}
@@ -0,0 +1,72 @@
1
+ import { headless } from './headless';
2
+ const groupMap = new WeakMap();
3
+ const getGroup = (el, Alpine) => {
4
+ const root = Alpine.findClosest(el, groupMap.has.bind(groupMap));
5
+ return groupMap.get(root);
6
+ };
7
+ const handleAccordionGroup = (el, _, { Alpine, effect }) => {
8
+ const groupData = Alpine.reactive({
9
+ active: null,
10
+ id: 0,
11
+ addAccordion(initial) {
12
+ const thisId = this.id++;
13
+ const accordionInstance = Alpine.reactive({
14
+ active: initial,
15
+ });
16
+ effect(() => {
17
+ if (accordionInstance.active) {
18
+ this.active = thisId;
19
+ }
20
+ else if (this.active === thisId) {
21
+ this.active = null;
22
+ }
23
+ });
24
+ effect(() => {
25
+ if (this.active === thisId) {
26
+ accordionInstance.active = true;
27
+ }
28
+ else {
29
+ accordionInstance.active = false;
30
+ }
31
+ });
32
+ return accordionInstance;
33
+ },
34
+ });
35
+ groupMap.set(el, groupData);
36
+ return groupData;
37
+ };
38
+ export const accordionGroup = (Alpine) => Alpine.directive('accordion-group', handleAccordionGroup);
39
+ const handleAccordionRoot = (el, { modifiers: [initialState = 'closed'] }, { Alpine }) => getGroup(el, Alpine)?.addAccordion(initialState === 'open') ??
40
+ Alpine.reactive({
41
+ active: initialState === 'open',
42
+ });
43
+ const controlForce = {
44
+ open: true,
45
+ close: false,
46
+ toggle: null,
47
+ };
48
+ const handleAccordionControl = (accordionData, el, { modifiers: [force = 'toggle'] }, { Alpine }) => {
49
+ Alpine.bind(el, {
50
+ 'x-on:click': () => {
51
+ accordionData.active =
52
+ controlForce[force] ?? !accordionData.active;
53
+ },
54
+ ':aria-expanded': () => accordionData.active,
55
+ });
56
+ };
57
+ const handleAccordionContainer = (accordionData, el, _, { Alpine }) => {
58
+ Alpine.bind(el, {
59
+ 'x-show': () => accordionData.active,
60
+ });
61
+ };
62
+ const accordionHandlers = {
63
+ control: handleAccordionControl,
64
+ container: handleAccordionContainer,
65
+ };
66
+ export const accordion = headless('accordion', handleAccordionRoot, accordionHandlers);
67
+ export const accordions = (Alpine) => {
68
+ accordionGroup(Alpine);
69
+ accordion(Alpine);
70
+ };
71
+ export default accordions;
72
+ //# sourceMappingURL=accordion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accordion.js","sourceRoot":"","sources":["../../src/headless/accordion.ts"],"names":[],"mappings":"AAGA,OAAO,EAAgC,QAAQ,EAAE,MAAM,YAAY,CAAC;AAOpE,MAAM,QAAQ,GAAG,IAAI,OAAO,EAA0B,CAAC;AAEvD,MAAM,QAAQ,GAAG,CAAC,EAAe,EAAE,MAAc,EAAE,EAAE;IACnD,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC,EAAE,EAAE,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;IACjE,OAAO,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC,CAAC;AAEF,MAAM,oBAAoB,GAA2B,CACnD,EAAE,EACF,CAAC,EACD,EAAE,MAAM,EAAE,MAAM,EAAE,EAClB,EAAE;IACF,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC;QAChC,MAAM,EAAE,IAAqB;QAC7B,EAAE,EAAE,CAAC;QACL,YAAY,CAAC,OAAgB;YAC3B,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;YACzB,MAAM,iBAAiB,GAAG,MAAM,CAAC,QAAQ,CAAC;gBACxC,MAAM,EAAE,OAAO;aAChB,CAAC,CAAC;YACH,MAAM,CAAC,GAAG,EAAE;gBACV,IAAI,iBAAiB,CAAC,MAAM,EAAE;oBAC5B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;iBACtB;qBAAM,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,EAAE;oBACjC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;iBACpB;YACH,CAAC,CAAC,CAAC;YACH,MAAM,CAAC,GAAG,EAAE;gBACV,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,EAAE;oBAC1B,iBAAiB,CAAC,MAAM,GAAG,IAAI,CAAC;iBACjC;qBAAM;oBACL,iBAAiB,CAAC,MAAM,GAAG,KAAK,CAAC;iBAClC;YACH,CAAC,CAAC,CAAC;YACH,OAAO,iBAAiB,CAAC;QAC3B,CAAC;KACF,CAAC,CAAC;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;IAC5B,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAiB,CAAC,MAAM,EAAE,EAAE,CACrD,MAAM,CAAC,SAAS,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,CAAC;AAK5D,MAAM,mBAAmB,GAA+B,CACtD,EAAE,EACF,EAAE,SAAS,EAAE,CAAC,YAAY,GAAG,QAAQ,CAAC,EAAE,EACxC,EAAE,MAAM,EAAE,EACV,EAAE,CACF,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,YAAY,CAAC,YAAY,KAAK,MAAM,CAAC;IAC3D,MAAM,CAAC,QAAQ,CAAC;QACd,MAAM,EAAE,YAAY,KAAK,MAAM;KAChC,CAAC,CAAC;AAEL,MAAM,YAAY,GAAG;IACnB,IAAI,EAAE,IAAI;IACV,KAAK,EAAE,KAAK;IACZ,MAAM,EAAE,IAAI;CACb,CAAC;AAIF,MAAM,sBAAsB,GAAmC,CAC7D,aAAa,EACb,EAAE,EACF,EAAE,SAAS,EAAE,CAAC,KAAK,GAAG,QAAQ,CAAC,EAAE,EACjC,EAAE,MAAM,EAAE,EACV,EAAE;IACF,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE;QACd,YAAY,EAAE,GAAG,EAAE;YACjB,aAAa,CAAC,MAAM;gBAClB,YAAY,CAAC,KAAoB,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC;QAChE,CAAC;QACD,gBAAgB,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,MAAM;KAC7C,CAAC,CAAC;AACL,CAAC,CAAC;AACF,MAAM,wBAAwB,GAAmC,CAC/D,aAAa,EACb,EAAE,EACF,CAAC,EACD,EAAE,MAAM,EAAE,EACV,EAAE;IACF,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE;QACd,QAAQ,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,MAAM;KACrC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAG;IACxB,OAAO,EAAE,sBAAsB;IAC/B,SAAS,EAAE,wBAAwB;CACpC,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG,QAAQ,CAC/B,WAAW,EACX,mBAAmB,EACnB,iBAAiB,CAClB,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAiB,CAAC,MAAM,EAAE,EAAE;IACjD,cAAc,CAAC,MAAM,CAAC,CAAC;IACvB,SAAS,CAAC,MAAM,CAAC,CAAC;AACpB,CAAC,CAAC;AACF,eAAe,UAAU,CAAC"}
@@ -1,9 +1,8 @@
1
- import type { Alpine } from 'alpinejs';
2
1
  import type { DirectiveData, ElementWithXAttributes, Utilities } from 'alpinejs/dist/types';
3
- export declare const headless: <T extends Record<string, unknown>>(name: string, rootHandler: RootHandler<T>, handlers?: HeadlessHandlers<T> | undefined) => HeadlessComponent;
2
+ import { AlpinePlugin } from '../types';
3
+ export declare const headless: <T extends Record<string, unknown>>(name: string, rootHandler: RootHandler<T>, handlers?: HeadlessHandlers<T> | undefined) => AlpinePlugin;
4
4
  type HeadlessHandlers<T extends Record<string, unknown>> = Record<string, HeadlessHandler<T>>;
5
5
  export type RootHandler<T> = (el: ElementWithXAttributes, directive: DirectiveData, utilities: Utilities) => T;
6
6
  export type HeadlessHandler<T> = (state: T, el: ElementWithXAttributes, directive: DirectiveData, utilities: Utilities) => void;
7
- export type HeadlessComponent = (Alpine: Alpine) => void;
8
7
  export {};
9
8
  //# sourceMappingURL=headless.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"headless.d.ts","sourceRoot":"","sources":["../../src/headless/headless.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,KAAK,EACV,aAAa,EACb,sBAAsB,EACtB,SAAS,EACV,MAAM,qBAAqB,CAAC;AAE7B,eAAO,MAAM,QAAQ,4CACb,MAAM,8EAGX,iBA2BF,CAAC;AAeF,KAAK,gBAAgB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,MAAM,CAC/D,MAAM,EACN,eAAe,CAAC,CAAC,CAAC,CACnB,CAAC;AAEF,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI,CAC3B,EAAE,EAAE,sBAAsB,EAC1B,SAAS,EAAE,aAAa,EACxB,SAAS,EAAE,SAAS,KACjB,CAAC,CAAC;AAEP,MAAM,MAAM,eAAe,CAAC,CAAC,IAAI,CAC/B,KAAK,EAAE,CAAC,EACR,EAAE,EAAE,sBAAsB,EAC1B,SAAS,EAAE,aAAa,EACxB,SAAS,EAAE,SAAS,KACjB,IAAI,CAAC;AAEV,MAAM,MAAM,iBAAiB,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC"}
1
+ {"version":3,"file":"headless.d.ts","sourceRoot":"","sources":["../../src/headless/headless.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,aAAa,EACb,sBAAsB,EACtB,SAAS,EACV,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC,eAAO,MAAM,QAAQ,4CACb,MAAM,8EAGX,YA2BF,CAAC;AAeF,KAAK,gBAAgB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,MAAM,CAC/D,MAAM,EACN,eAAe,CAAC,CAAC,CAAC,CACnB,CAAC;AAEF,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI,CAC3B,EAAE,EAAE,sBAAsB,EAC1B,SAAS,EAAE,aAAa,EACxB,SAAS,EAAE,SAAS,KACjB,CAAC,CAAC;AAEP,MAAM,MAAM,eAAe,CAAC,CAAC,IAAI,CAC/B,KAAK,EAAE,CAAC,EACR,EAAE,EAAE,sBAAsB,EAC1B,SAAS,EAAE,aAAa,EACxB,SAAS,EAAE,SAAS,KACjB,IAAI,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"headless.js","sourceRoot":"","sources":["../../src/headless/headless.ts"],"names":[],"mappings":"AAOA,MAAM,CAAC,MAAM,QAAQ,GAAG,CACtB,IAAY,EACZ,WAA2B,EAC3B,QAA8B,EACX,EAAE;IACrB,MAAM,WAAW,GAAG,IAAI,OAAO,EAA6B,CAAC;IAC7D,OAAO,CAAC,MAAc,EAAE,EAAE;QACxB,MAAM,yBAAyB,GAAG,CAChC,EAA0B,EAChB,EAAE;YACZ,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC,EAAE,EAAE,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;YACvE,IAAI,CAAC,IAAI;gBACP,OAAO,OAAO,CAAC,KAAK,CAAC,2BAA2B,IAAI,YAAY,EAAE,EAAE,CAAC,CAAC;YACxE,OAAO,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC,CAAC;QAEF,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,yBAAyB,CAAC,EAAE,CAAC,CAAC,CAAC;QAE1D,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE;YAC9C,IAAI,CAAC,SAAS,CAAC,KAAK;gBAClB,OAAO,WAAW,CAAC,GAAG,CAAC,EAAE,EAAE,WAAW,CAAC,EAAE,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC;YAChE,MAAM,aAAa,GAAG,yBAAyB,CAAC,EAAE,CAAC,CAAC;YACpD,IAAI,CAAC,aAAa;gBAAE,OAAO,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YAClD,CAAC,QAAQ,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAC7C,aAAa,EACb,EAAE,EACF,SAAS,EACT,KAAK,CACN,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,QAAQ,GACZ,CAAC,IAAY,EAAE,EAAE,CACjB,CAAC,CAAU,EAAE,EAA0B,EAAE,SAAwB,EAAE,EAAE;IACnE,OAAO,CAAC,KAAK,CACX,UAAU,IAAI,2BAA2B,EACzC,EAAE,EACF,SAAS,CAAC,QAAQ,CACnB,CAAC;AACJ,CAAC,CAAC;AAEJ,MAAM,YAAY,GAAG,CAAC,IAAY,EAAE,EAA0B,EAAE,EAAE,CAChE,OAAO,CAAC,KAAK,CAAC,2BAA2B,IAAI,YAAY,EAAE,EAAE,CAAC,CAAC"}
1
+ {"version":3,"file":"headless.js","sourceRoot":"","sources":["../../src/headless/headless.ts"],"names":[],"mappings":"AASA,MAAM,CAAC,MAAM,QAAQ,GAAG,CACtB,IAAY,EACZ,WAA2B,EAC3B,QAA8B,EAChB,EAAE;IAChB,MAAM,WAAW,GAAG,IAAI,OAAO,EAA6B,CAAC;IAC7D,OAAO,CAAC,MAAc,EAAE,EAAE;QACxB,MAAM,yBAAyB,GAAG,CAChC,EAA0B,EAChB,EAAE;YACZ,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC,EAAE,EAAE,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;YACvE,IAAI,CAAC,IAAI;gBACP,OAAO,OAAO,CAAC,KAAK,CAAC,2BAA2B,IAAI,YAAY,EAAE,EAAE,CAAC,CAAC;YACxE,OAAO,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC,CAAC;QAEF,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,yBAAyB,CAAC,EAAE,CAAC,CAAC,CAAC;QAE1D,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE;YAC9C,IAAI,CAAC,SAAS,CAAC,KAAK;gBAClB,OAAO,WAAW,CAAC,GAAG,CAAC,EAAE,EAAE,WAAW,CAAC,EAAE,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC;YAChE,MAAM,aAAa,GAAG,yBAAyB,CAAC,EAAE,CAAC,CAAC;YACpD,IAAI,CAAC,aAAa;gBAAE,OAAO,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YAClD,CAAC,QAAQ,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAC7C,aAAa,EACb,EAAE,EACF,SAAS,EACT,KAAK,CACN,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,QAAQ,GACZ,CAAC,IAAY,EAAE,EAAE,CACjB,CAAC,CAAU,EAAE,EAA0B,EAAE,SAAwB,EAAE,EAAE;IACnE,OAAO,CAAC,KAAK,CACX,UAAU,IAAI,2BAA2B,EACzC,EAAE,EACF,SAAS,CAAC,QAAQ,CACnB,CAAC;AACJ,CAAC,CAAC;AAEJ,MAAM,YAAY,GAAG,CAAC,IAAY,EAAE,EAA0B,EAAE,EAAE,CAChE,OAAO,CAAC,KAAK,CAAC,2BAA2B,IAAI,YAAY,EAAE,EAAE,CAAC,CAAC"}
@@ -0,0 +1,6 @@
1
+ export { accordionGroup, accordion, accordions } from './accordion';
2
+ export { headless } from './headless';
3
+ export { panel } from './panel';
4
+ export { tabs } from './tabs';
5
+ export type { RootHandler, HeadlessHandler } from './headless';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/headless/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { accordionGroup, accordion, accordions } from './accordion';
2
+ export { headless } from './headless';
3
+ export { panel } from './panel';
4
+ export { tabs } from './tabs';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/headless/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC"}
@@ -1,2 +1,2 @@
1
- export declare const panel: import("./headless").HeadlessComponent;
1
+ export declare const panel: import("..").AlpinePlugin;
2
2
  //# sourceMappingURL=panel.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"panel.d.ts","sourceRoot":"","sources":["../../src/headless/panel.ts"],"names":[],"mappings":"AA8BA,eAAO,MAAM,KAAK,wCAYhB,CAAC"}
1
+ {"version":3,"file":"panel.d.ts","sourceRoot":"","sources":["../../src/headless/panel.ts"],"names":[],"mappings":"AA8BA,eAAO,MAAM,KAAK,2BAYhB,CAAC"}
@@ -1,2 +1,2 @@
1
- export declare const tabs: import("./headless").HeadlessComponent;
1
+ export declare const tabs: import("..").AlpinePlugin;
2
2
  //# sourceMappingURL=tabs.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tabs.d.ts","sourceRoot":"","sources":["../../src/headless/tabs.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,IAAI,wCAkDhB,CAAC"}
1
+ {"version":3,"file":"tabs.d.ts","sourceRoot":"","sources":["../../src/headless/tabs.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,IAAI,2BAkDhB,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,8 @@
1
- import { HeadlessComponent } from './headless/headless';
2
- export declare const UI: HeadlessComponent;
1
+ import { accordion, accordionGroup, accordions, panel, tabs } from './headless';
2
+ import { screen } from './magics';
3
+ import type { AlpinePlugin } from './types';
4
+ export declare const NTMagics: AlpinePlugin;
5
+ export declare const UI: AlpinePlugin;
3
6
  export default UI;
7
+ export { accordion, accordionGroup, accordions, panel, tabs, screen, AlpinePlugin, };
4
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAIxD,eAAO,MAAM,EAAE,EAAE,iBAA4D,CAAC;AAE9E,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAChF,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C,eAAO,MAAM,QAAQ,EAAE,YAAkD,CAAC;AAE1E,eAAO,MAAM,EAAE,EAAE,YACmC,CAAC;AAErD,eAAe,EAAE,CAAC;AAElB,OAAO,EACL,SAAS,EACT,cAAc,EACd,UAAU,EACV,KAAK,EACL,IAAI,EACJ,MAAM,EACN,YAAY,GACb,CAAC"}
package/dist/index.js CHANGED
@@ -1,5 +1,7 @@
1
- import { panel } from './headless/panel';
2
- import { tabs } from './headless/tabs';
3
- export const UI = (Alpine) => Alpine.plugin([panel, tabs]);
1
+ import { accordion, accordionGroup, accordions, panel, tabs } from './headless';
2
+ import { screen } from './magics';
3
+ export const NTMagics = (Alpine) => Alpine.plugin([screen]);
4
+ export const UI = (Alpine) => Alpine.plugin([accordions, panel, tabs, NTMagics]);
4
5
  export default UI;
6
+ export { accordion, accordionGroup, accordions, panel, tabs, screen, };
5
7
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAEvC,MAAM,CAAC,MAAM,EAAE,GAAsB,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;AAE9E,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAChF,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAGlC,MAAM,CAAC,MAAM,QAAQ,GAAiB,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAE1E,MAAM,CAAC,MAAM,EAAE,GAAiB,CAAC,MAAM,EAAE,EAAE,CACzC,MAAM,CAAC,MAAM,CAAC,CAAC,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;AAErD,eAAe,EAAE,CAAC;AAElB,OAAO,EACL,SAAS,EACT,cAAc,EACd,UAAU,EACV,KAAK,EACL,IAAI,EACJ,MAAM,GAEP,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { screen } from './screen';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/magics/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { screen } from './screen';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/magics/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { AlpinePlugin } from '../types';
2
+ export declare const screen: AlpinePlugin;
3
+ //# sourceMappingURL=screen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screen.d.ts","sourceRoot":"","sources":["../../src/magics/screen.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC,eAAO,MAAM,MAAM,EAAE,YAepB,CAAC"}
@@ -0,0 +1,40 @@
1
+ import Alpine from 'alpinejs';
2
+ export const screen = (Alpine) => {
3
+ Alpine.magic('screen', () => (breakpoint) => {
4
+ const breakSize = typeof breakpoint === 'number'
5
+ ? breakpoint
6
+ : breakpoints[breakpoint] ?? Number(breakpoint);
7
+ if (!breakSize) {
8
+ console.error(`Invalid breakpoint: $screen(${JSON.stringify(breakpoint)})`);
9
+ return false;
10
+ }
11
+ const signal = getMediaSignal(breakSize);
12
+ return signal.value;
13
+ });
14
+ };
15
+ // Configuration
16
+ const defaultBreakpoints = {
17
+ xs: 320,
18
+ sm: 640,
19
+ md: 768,
20
+ lg: 1024,
21
+ xl: 1280,
22
+ '2xl': 1536,
23
+ };
24
+ const breakpoints = defaultBreakpoints;
25
+ const mediaSignals = {};
26
+ const getMediaSignal = (breakpoint) => {
27
+ return mediaSignals[breakpoint] ?? createMediaSignal(breakpoint);
28
+ };
29
+ const createMediaSignal = (breakpoint) => {
30
+ const mediaMatch = window.matchMedia(`(min-width: ${breakpoint}px)`);
31
+ const signal = Alpine.reactive({
32
+ value: mediaMatch.matches,
33
+ });
34
+ mediaSignals[breakpoint] = signal;
35
+ mediaMatch.addEventListener('change', (e) => {
36
+ signal.value = e.matches;
37
+ });
38
+ return signal;
39
+ };
40
+ //# sourceMappingURL=screen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screen.js","sourceRoot":"","sources":["../../src/magics/screen.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,UAAU,CAAC;AAI9B,MAAM,CAAC,MAAM,MAAM,GAAiB,CAAC,MAAM,EAAE,EAAE;IAC7C,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,UAA2B,EAAE,EAAE;QAC3D,MAAM,SAAS,GACb,OAAO,UAAU,KAAK,QAAQ;YAC5B,CAAC,CAAC,UAAU;YACZ,CAAC,CAAC,WAAW,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,CAAC;QACpD,IAAI,CAAC,SAAS,EAAE;YACd,OAAO,CAAC,KAAK,CACX,+BAA+B,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,CAC7D,CAAC;YACF,OAAO,KAAK,CAAC;SACd;QACD,MAAM,MAAM,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;QACzC,OAAO,MAAM,CAAC,KAAK,CAAC;IACtB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,gBAAgB;AAChB,MAAM,kBAAkB,GAA2B;IACjD,EAAE,EAAE,GAAG;IACP,EAAE,EAAE,GAAG;IACP,EAAE,EAAE,GAAG;IACP,EAAE,EAAE,IAAI;IACR,EAAE,EAAE,IAAI;IACR,KAAK,EAAE,IAAI;CACZ,CAAC;AAEF,MAAM,WAAW,GAAG,kBAAkB,CAAC;AACvC,MAAM,YAAY,GAAuC,EAAE,CAAC;AAE5D,MAAM,cAAc,GAAG,CAAC,UAAkB,EAAE,EAAE;IAC5C,OAAO,YAAY,CAAC,UAAU,CAAC,IAAI,iBAAiB,CAAC,UAAU,CAAC,CAAC;AACnE,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAG,CAAC,UAAkB,EAAE,EAAE;IAC/C,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,eAAe,UAAU,KAAK,CAAC,CAAC;IACrE,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC;QAC7B,KAAK,EAAE,UAAU,CAAC,OAAO;KAC1B,CAAC,CAAC;IACH,YAAY,CAAC,UAAU,CAAC,GAAG,MAAM,CAAC;IAClC,UAAU,CAAC,gBAAgB,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE;QAC1C,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,OAAO,CAAC;IAC3B,CAAC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,20 @@
1
1
  {
2
2
  "name": "@newthink/ui",
3
- "version": "0.1.3",
3
+ "version": "0.3.0",
4
4
  "description": "Simple Alpine Headless UI Components",
5
+ "author": {
6
+ "name": "Eric Kwoka",
7
+ "email": "ninjatheory@gmail.com",
8
+ "url": "https://thekwoka.net/"
9
+ },
10
+ "repository": "github:ekwoka/newthink-ui",
11
+ "keywords": [
12
+ "alpinejs",
13
+ "headless",
14
+ "components",
15
+ "plugins"
16
+ ],
17
+ "license": "ISC",
5
18
  "main": "dist/index.js",
6
19
  "module": "dist/index.js",
7
20
  "types": "dist/index.d.ts",
@@ -17,27 +30,25 @@
17
30
  "src"
18
31
  ],
19
32
  "type": "module",
20
- "keywords": [],
21
- "author": "",
22
- "license": "ISC",
33
+ "sideeffects": false,
23
34
  "devDependencies": {
24
- "@trivago/prettier-plugin-sort-imports": "4.1.1",
25
- "@types/node": "20.2.5",
26
- "@typescript-eslint/eslint-plugin": "5.59.9",
27
- "@typescript-eslint/parser": "5.59.9",
28
- "@vitest/coverage-c8": "0.32.0",
35
+ "@trivago/prettier-plugin-sort-imports": "4.2.0",
36
+ "@types/node": "20.5.0",
37
+ "@typescript-eslint/eslint-plugin": "6.3.0",
38
+ "@typescript-eslint/parser": "6.3.0",
39
+ "@vitest/coverage-c8": "0.32.1",
29
40
  "alpinejs": "npm:@ekwoka/alpinets@0.0.1-alpha",
30
- "esbuild": "0.17.19",
31
- "eslint": "8.42.0",
32
- "eslint-plugin-filename-export": "1.0.3",
41
+ "esbuild": "0.19.2",
42
+ "eslint": "8.47.0",
43
+ "eslint-plugin-filename-export": "1.0.4",
33
44
  "husky": "8.0.3",
34
- "lint-staged": "13.2.2",
35
- "prettier": "2.8.8",
36
- "pretty-bytes": "^6.1.0",
37
- "typescript": "5.1.3",
38
- "vite": "4.3.9",
45
+ "lint-staged": "14.0.0",
46
+ "prettier": "3.0.1",
47
+ "pretty-bytes": "6.1.1",
48
+ "typescript": "5.1.6",
49
+ "vite": "4.4.9",
39
50
  "vite-tsconfig-paths": "4.2.0",
40
- "vitest": "0.32.0"
51
+ "vitest": "0.34.1"
41
52
  },
42
53
  "peerDependencies": {
43
54
  "alpinejs": "^3.10.0",
@@ -0,0 +1,116 @@
1
+ import { Alpine } from 'alpinejs';
2
+
3
+ import { AlpinePlugin } from '../types';
4
+ import { HeadlessHandler, RootHandler, headless } from './headless';
5
+
6
+ type GroupData = {
7
+ active: number | null;
8
+ id: number;
9
+ addAccordion: (initial: boolean) => AccordionData;
10
+ };
11
+ const groupMap = new WeakMap<HTMLElement, GroupData>();
12
+
13
+ const getGroup = (el: HTMLElement, Alpine: Alpine) => {
14
+ const root = Alpine.findClosest(el, groupMap.has.bind(groupMap));
15
+ return groupMap.get(root);
16
+ };
17
+
18
+ const handleAccordionGroup: RootHandler<GroupData> = (
19
+ el,
20
+ _,
21
+ { Alpine, effect },
22
+ ) => {
23
+ const groupData = Alpine.reactive({
24
+ active: null as number | null,
25
+ id: 0,
26
+ addAccordion(initial: boolean) {
27
+ const thisId = this.id++;
28
+ const accordionInstance = Alpine.reactive({
29
+ active: initial,
30
+ });
31
+ effect(() => {
32
+ if (accordionInstance.active) {
33
+ this.active = thisId;
34
+ } else if (this.active === thisId) {
35
+ this.active = null;
36
+ }
37
+ });
38
+ effect(() => {
39
+ if (this.active === thisId) {
40
+ accordionInstance.active = true;
41
+ } else {
42
+ accordionInstance.active = false;
43
+ }
44
+ });
45
+ return accordionInstance;
46
+ },
47
+ });
48
+ groupMap.set(el, groupData);
49
+ return groupData;
50
+ };
51
+
52
+ export const accordionGroup: AlpinePlugin = (Alpine) =>
53
+ Alpine.directive('accordion-group', handleAccordionGroup);
54
+
55
+ type AccordionData = {
56
+ active: boolean;
57
+ };
58
+ const handleAccordionRoot: RootHandler<AccordionData> = (
59
+ el,
60
+ { modifiers: [initialState = 'closed'] },
61
+ { Alpine },
62
+ ) =>
63
+ getGroup(el, Alpine)?.addAccordion(initialState === 'open') ??
64
+ Alpine.reactive({
65
+ active: initialState === 'open',
66
+ });
67
+
68
+ const controlForce = {
69
+ open: true,
70
+ close: false,
71
+ toggle: null,
72
+ };
73
+
74
+ type controlType = keyof typeof controlForce;
75
+
76
+ const handleAccordionControl: HeadlessHandler<AccordionData> = (
77
+ accordionData,
78
+ el,
79
+ { modifiers: [force = 'toggle'] },
80
+ { Alpine },
81
+ ) => {
82
+ Alpine.bind(el, {
83
+ 'x-on:click': () => {
84
+ accordionData.active =
85
+ controlForce[force as controlType] ?? !accordionData.active;
86
+ },
87
+ ':aria-expanded': () => accordionData.active,
88
+ });
89
+ };
90
+ const handleAccordionContainer: HeadlessHandler<AccordionData> = (
91
+ accordionData,
92
+ el,
93
+ _,
94
+ { Alpine },
95
+ ) => {
96
+ Alpine.bind(el, {
97
+ 'x-show': () => accordionData.active,
98
+ });
99
+ };
100
+
101
+ const accordionHandlers = {
102
+ control: handleAccordionControl,
103
+ container: handleAccordionContainer,
104
+ };
105
+
106
+ export const accordion = headless(
107
+ 'accordion',
108
+ handleAccordionRoot,
109
+ accordionHandlers,
110
+ );
111
+
112
+ export const accordions: AlpinePlugin = (Alpine) => {
113
+ accordionGroup(Alpine);
114
+ accordion(Alpine);
115
+ };
116
+ export default accordions;
@@ -5,15 +5,17 @@ import type {
5
5
  Utilities,
6
6
  } from 'alpinejs/dist/types';
7
7
 
8
+ import { AlpinePlugin } from '../types';
9
+
8
10
  export const headless = <T extends Record<string, unknown>>(
9
11
  name: string,
10
12
  rootHandler: RootHandler<T>,
11
- handlers?: HeadlessHandlers<T>
12
- ): HeadlessComponent => {
13
+ handlers?: HeadlessHandlers<T>,
14
+ ): AlpinePlugin => {
13
15
  const headlessMap = new WeakMap<ElementWithXAttributes, T>();
14
16
  return (Alpine: Alpine) => {
15
17
  const getHeadlessComponentState = (
16
- el: ElementWithXAttributes
18
+ el: ElementWithXAttributes,
17
19
  ): T | void => {
18
20
  const root = Alpine.findClosest(el, headlessMap.has.bind(headlessMap));
19
21
  if (!root)
@@ -32,7 +34,7 @@ export const headless = <T extends Record<string, unknown>>(
32
34
  headlessState,
33
35
  el,
34
36
  directive,
35
- utils
37
+ utils,
36
38
  );
37
39
  });
38
40
  };
@@ -44,7 +46,7 @@ const failback =
44
46
  console.error(
45
47
  `Alpine ${name}: Invalid directive value`,
46
48
  el,
47
- directive.original
49
+ directive.original,
48
50
  );
49
51
  };
50
52
 
@@ -59,14 +61,12 @@ type HeadlessHandlers<T extends Record<string, unknown>> = Record<
59
61
  export type RootHandler<T> = (
60
62
  el: ElementWithXAttributes,
61
63
  directive: DirectiveData,
62
- utilities: Utilities
64
+ utilities: Utilities,
63
65
  ) => T;
64
66
 
65
67
  export type HeadlessHandler<T> = (
66
68
  state: T,
67
69
  el: ElementWithXAttributes,
68
70
  directive: DirectiveData,
69
- utilities: Utilities
71
+ utilities: Utilities,
70
72
  ) => void;
71
-
72
- export type HeadlessComponent = (Alpine: Alpine) => void;
@@ -0,0 +1,5 @@
1
+ export { accordionGroup, accordion, accordions } from './accordion';
2
+ export { headless } from './headless';
3
+ export { panel } from './panel';
4
+ export { tabs } from './tabs';
5
+ export type { RootHandler, HeadlessHandler } from './headless';
@@ -49,7 +49,7 @@ export const tabs = headless(
49
49
  ':aria-hidden': () => panelIndex !== tabGroup.activeTab,
50
50
  });
51
51
  },
52
- }
52
+ },
53
53
  );
54
54
 
55
55
  type FocusMagic = {
package/src/index.ts CHANGED
@@ -1,7 +1,20 @@
1
- import { HeadlessComponent } from './headless/headless';
2
- import { panel } from './headless/panel';
3
- import { tabs } from './headless/tabs';
1
+ import { accordion, accordionGroup, accordions, panel, tabs } from './headless';
2
+ import { screen } from './magics';
3
+ import type { AlpinePlugin } from './types';
4
4
 
5
- export const UI: HeadlessComponent = (Alpine) => Alpine.plugin([panel, tabs]);
5
+ export const NTMagics: AlpinePlugin = (Alpine) => Alpine.plugin([screen]);
6
+
7
+ export const UI: AlpinePlugin = (Alpine) =>
8
+ Alpine.plugin([accordions, panel, tabs, NTMagics]);
6
9
 
7
10
  export default UI;
11
+
12
+ export {
13
+ accordion,
14
+ accordionGroup,
15
+ accordions,
16
+ panel,
17
+ tabs,
18
+ screen,
19
+ AlpinePlugin,
20
+ };
@@ -0,0 +1 @@
1
+ export { screen } from './screen';
@@ -0,0 +1,49 @@
1
+ import Alpine from 'alpinejs';
2
+
3
+ import { AlpinePlugin } from '../types';
4
+
5
+ export const screen: AlpinePlugin = (Alpine) => {
6
+ Alpine.magic('screen', () => (breakpoint: string | number) => {
7
+ const breakSize =
8
+ typeof breakpoint === 'number'
9
+ ? breakpoint
10
+ : breakpoints[breakpoint] ?? Number(breakpoint);
11
+ if (!breakSize) {
12
+ console.error(
13
+ `Invalid breakpoint: $screen(${JSON.stringify(breakpoint)})`,
14
+ );
15
+ return false;
16
+ }
17
+ const signal = getMediaSignal(breakSize);
18
+ return signal.value;
19
+ });
20
+ };
21
+
22
+ // Configuration
23
+ const defaultBreakpoints: Record<string, number> = {
24
+ xs: 320,
25
+ sm: 640,
26
+ md: 768,
27
+ lg: 1024,
28
+ xl: 1280,
29
+ '2xl': 1536,
30
+ };
31
+
32
+ const breakpoints = defaultBreakpoints;
33
+ const mediaSignals: Record<number, { value: boolean }> = {};
34
+
35
+ const getMediaSignal = (breakpoint: number) => {
36
+ return mediaSignals[breakpoint] ?? createMediaSignal(breakpoint);
37
+ };
38
+
39
+ const createMediaSignal = (breakpoint: number) => {
40
+ const mediaMatch = window.matchMedia(`(min-width: ${breakpoint}px)`);
41
+ const signal = Alpine.reactive({
42
+ value: mediaMatch.matches,
43
+ });
44
+ mediaSignals[breakpoint] = signal;
45
+ mediaMatch.addEventListener('change', (e) => {
46
+ signal.value = e.matches;
47
+ });
48
+ return signal;
49
+ };
package/src/types.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import { Alpine } from 'alpinejs';
2
+
3
+ export type AlpinePlugin = (Alpine: Alpine) => void;