@studiometa/ui 0.2.22 → 0.2.24

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.
Files changed (195) hide show
  1. package/README.md +2 -12
  2. package/atoms/AnchorScrollTo/AnchorScrollTo.cjs +11 -0
  3. package/atoms/AnchorScrollTo/AnchorScrollTo.cjs.map +2 -2
  4. package/atoms/AnchorScrollTo/AnchorScrollTo.js +11 -0
  5. package/atoms/AnchorScrollTo/AnchorScrollTo.js.map +2 -2
  6. package/atoms/Button/StyledButton.twig +6 -4
  7. package/atoms/Button/StyledButtonRounded.twig +65 -0
  8. package/atoms/Cursor/Cursor.cjs +12 -0
  9. package/atoms/Cursor/Cursor.cjs.map +2 -2
  10. package/atoms/Cursor/Cursor.js +12 -0
  11. package/atoms/Cursor/Cursor.js.map +2 -2
  12. package/atoms/Figure/Figure.cjs +31 -4
  13. package/atoms/Figure/Figure.cjs.map +2 -2
  14. package/atoms/Figure/Figure.d.ts +4 -0
  15. package/atoms/Figure/Figure.js +31 -4
  16. package/atoms/Figure/Figure.js.map +2 -2
  17. package/atoms/Figure/Figure.twig +6 -1
  18. package/atoms/Figure/FigureTwicpics.cjs +28 -4
  19. package/atoms/Figure/FigureTwicpics.cjs.map +2 -2
  20. package/atoms/Figure/FigureTwicpics.d.ts +6 -2
  21. package/atoms/Figure/FigureTwicpics.js +28 -4
  22. package/atoms/Figure/FigureTwicpics.js.map +2 -2
  23. package/atoms/Figure/FigureTwicpics.twig +6 -0
  24. package/atoms/LargeText/LargeText.cjs +27 -0
  25. package/atoms/LargeText/LargeText.cjs.map +2 -2
  26. package/atoms/LargeText/LargeText.js +27 -0
  27. package/atoms/LargeText/LargeText.js.map +2 -2
  28. package/atoms/LazyInclude/LazyInclude.cjs +15 -0
  29. package/atoms/LazyInclude/LazyInclude.cjs.map +2 -2
  30. package/atoms/LazyInclude/LazyInclude.js +15 -0
  31. package/atoms/LazyInclude/LazyInclude.js.map +2 -2
  32. package/atoms/Prefetch/AbstractPrefetch.cjs +12 -0
  33. package/atoms/Prefetch/AbstractPrefetch.cjs.map +2 -2
  34. package/atoms/Prefetch/AbstractPrefetch.js +12 -0
  35. package/atoms/Prefetch/AbstractPrefetch.js.map +2 -2
  36. package/atoms/Prefetch/PrefetchWhenOver.cjs +6 -0
  37. package/atoms/Prefetch/PrefetchWhenOver.cjs.map +2 -2
  38. package/atoms/Prefetch/PrefetchWhenOver.js +6 -0
  39. package/atoms/Prefetch/PrefetchWhenOver.js.map +2 -2
  40. package/atoms/Prefetch/PrefetchWhenVisible.cjs +6 -0
  41. package/atoms/Prefetch/PrefetchWhenVisible.cjs.map +2 -2
  42. package/atoms/Prefetch/PrefetchWhenVisible.js +6 -0
  43. package/atoms/Prefetch/PrefetchWhenVisible.js.map +2 -2
  44. package/atoms/ScrollAnimation/AbstractScrollAnimation.cjs +12 -0
  45. package/atoms/ScrollAnimation/AbstractScrollAnimation.cjs.map +2 -2
  46. package/atoms/ScrollAnimation/AbstractScrollAnimation.js +12 -0
  47. package/atoms/ScrollAnimation/AbstractScrollAnimation.js.map +2 -2
  48. package/atoms/ScrollAnimation/ScrollAnimation.cjs +6 -0
  49. package/atoms/ScrollAnimation/ScrollAnimation.cjs.map +1 -1
  50. package/atoms/ScrollAnimation/ScrollAnimation.js +6 -0
  51. package/atoms/ScrollAnimation/ScrollAnimation.js.map +1 -1
  52. package/atoms/ScrollAnimation/ScrollAnimationChild.cjs +18 -1
  53. package/atoms/ScrollAnimation/ScrollAnimationChild.cjs.map +2 -2
  54. package/atoms/ScrollAnimation/ScrollAnimationChild.js +18 -1
  55. package/atoms/ScrollAnimation/ScrollAnimationChild.js.map +2 -2
  56. package/atoms/ScrollAnimation/ScrollAnimationChildWithEase.cjs +3 -0
  57. package/atoms/ScrollAnimation/ScrollAnimationChildWithEase.cjs.map +1 -1
  58. package/atoms/ScrollAnimation/ScrollAnimationChildWithEase.js +3 -0
  59. package/atoms/ScrollAnimation/ScrollAnimationChildWithEase.js.map +1 -1
  60. package/atoms/ScrollAnimation/ScrollAnimationParent.cjs +6 -0
  61. package/atoms/ScrollAnimation/ScrollAnimationParent.cjs.map +1 -1
  62. package/atoms/ScrollAnimation/ScrollAnimationParent.js +6 -0
  63. package/atoms/ScrollAnimation/ScrollAnimationParent.js.map +1 -1
  64. package/atoms/ScrollAnimation/ScrollAnimationWithEase.cjs +3 -0
  65. package/atoms/ScrollAnimation/ScrollAnimationWithEase.cjs.map +1 -1
  66. package/atoms/ScrollAnimation/ScrollAnimationWithEase.js +3 -0
  67. package/atoms/ScrollAnimation/ScrollAnimationWithEase.js.map +1 -1
  68. package/atoms/ScrollAnimation/animationScrollWithEase.cjs +6 -0
  69. package/atoms/ScrollAnimation/animationScrollWithEase.cjs.map +2 -2
  70. package/atoms/ScrollAnimation/animationScrollWithEase.js +6 -0
  71. package/atoms/ScrollAnimation/animationScrollWithEase.js.map +2 -2
  72. package/atoms/ScrollReveal/ScrollReveal.cjs +12 -0
  73. package/atoms/ScrollReveal/ScrollReveal.cjs.map +1 -1
  74. package/atoms/ScrollReveal/ScrollReveal.js +12 -0
  75. package/atoms/ScrollReveal/ScrollReveal.js.map +1 -1
  76. package/decorators/withTransition.cjs +16 -2
  77. package/decorators/withTransition.cjs.map +2 -2
  78. package/decorators/withTransition.js +16 -2
  79. package/decorators/withTransition.js.map +2 -2
  80. package/molecules/Accordion/AccordionCore.cjs +9 -0
  81. package/molecules/Accordion/AccordionCore.cjs.map +2 -2
  82. package/molecules/Accordion/AccordionCore.js +9 -0
  83. package/molecules/Accordion/AccordionCore.js.map +2 -2
  84. package/molecules/Accordion/AccordionItem.cjs +33 -1
  85. package/molecules/Accordion/AccordionItem.cjs.map +2 -2
  86. package/molecules/Accordion/AccordionItem.d.ts +1 -1
  87. package/molecules/Accordion/AccordionItem.js +29 -1
  88. package/molecules/Accordion/AccordionItem.js.map +2 -2
  89. package/molecules/Menu/Menu.cjs +47 -0
  90. package/molecules/Menu/Menu.cjs.map +1 -1
  91. package/molecules/Menu/Menu.js +47 -0
  92. package/molecules/Menu/Menu.js.map +1 -1
  93. package/molecules/Menu/MenuBtn.cjs +24 -0
  94. package/molecules/Menu/MenuBtn.cjs.map +1 -1
  95. package/molecules/Menu/MenuBtn.js +24 -0
  96. package/molecules/Menu/MenuBtn.js.map +1 -1
  97. package/molecules/Menu/MenuList.cjs +39 -0
  98. package/molecules/Menu/MenuList.cjs.map +2 -2
  99. package/molecules/Menu/MenuList.js +39 -0
  100. package/molecules/Menu/MenuList.js.map +2 -2
  101. package/molecules/Modal/Modal.cjs +50 -1
  102. package/molecules/Modal/Modal.cjs.map +2 -2
  103. package/molecules/Modal/Modal.d.ts +3 -3
  104. package/molecules/Modal/Modal.js +50 -1
  105. package/molecules/Modal/Modal.js.map +2 -2
  106. package/molecules/Modal/ModalWithTransition.cjs +6 -0
  107. package/molecules/Modal/ModalWithTransition.cjs.map +2 -2
  108. package/molecules/Modal/ModalWithTransition.js +6 -0
  109. package/molecules/Modal/ModalWithTransition.js.map +2 -2
  110. package/molecules/Panel/Panel.cjs +19 -0
  111. package/molecules/Panel/Panel.cjs.map +2 -2
  112. package/molecules/Panel/Panel.js +19 -0
  113. package/molecules/Panel/Panel.js.map +2 -2
  114. package/molecules/Slider/AbstractSliderChild.cjs +24 -0
  115. package/molecules/Slider/AbstractSliderChild.cjs.map +2 -2
  116. package/molecules/Slider/AbstractSliderChild.js +24 -0
  117. package/molecules/Slider/AbstractSliderChild.js.map +2 -2
  118. package/molecules/Slider/Slider.cjs +97 -0
  119. package/molecules/Slider/Slider.cjs.map +2 -2
  120. package/molecules/Slider/Slider.d.ts +3 -2
  121. package/molecules/Slider/Slider.js +97 -0
  122. package/molecules/Slider/Slider.js.map +2 -2
  123. package/molecules/Slider/SliderBtn.cjs +22 -2
  124. package/molecules/Slider/SliderBtn.cjs.map +2 -2
  125. package/molecules/Slider/SliderBtn.d.ts +1 -0
  126. package/molecules/Slider/SliderBtn.js +22 -2
  127. package/molecules/Slider/SliderBtn.js.map +2 -2
  128. package/molecules/Slider/SliderCount.cjs +9 -0
  129. package/molecules/Slider/SliderCount.cjs.map +2 -2
  130. package/molecules/Slider/SliderCount.js +9 -0
  131. package/molecules/Slider/SliderCount.js.map +2 -2
  132. package/molecules/Slider/SliderDots.cjs +19 -0
  133. package/molecules/Slider/SliderDots.cjs.map +2 -2
  134. package/molecules/Slider/SliderDots.js +19 -0
  135. package/molecules/Slider/SliderDots.js.map +2 -2
  136. package/molecules/Slider/SliderDrag.cjs +15 -0
  137. package/molecules/Slider/SliderDrag.cjs.map +2 -2
  138. package/molecules/Slider/SliderDrag.js +15 -0
  139. package/molecules/Slider/SliderDrag.js.map +2 -2
  140. package/molecules/Slider/SliderItem.cjs +75 -14
  141. package/molecules/Slider/SliderItem.cjs.map +2 -2
  142. package/molecules/Slider/SliderItem.d.ts +12 -11
  143. package/molecules/Slider/SliderItem.js +75 -14
  144. package/molecules/Slider/SliderItem.js.map +2 -2
  145. package/molecules/Slider/SliderProgress.cjs +6 -0
  146. package/molecules/Slider/SliderProgress.cjs.map +2 -2
  147. package/molecules/Slider/SliderProgress.js +6 -0
  148. package/molecules/Slider/SliderProgress.js.map +2 -2
  149. package/molecules/Sticky/Sticky.cjs +56 -0
  150. package/molecules/Sticky/Sticky.cjs.map +2 -2
  151. package/molecules/Sticky/Sticky.js +56 -0
  152. package/molecules/Sticky/Sticky.js.map +2 -2
  153. package/molecules/TableOfContent/TableOfContent.cjs +13 -0
  154. package/molecules/TableOfContent/TableOfContent.cjs.map +1 -1
  155. package/molecules/TableOfContent/TableOfContent.js +13 -0
  156. package/molecules/TableOfContent/TableOfContent.js.map +1 -1
  157. package/molecules/TableOfContent/TableOfContentAnchor.cjs +16 -0
  158. package/molecules/TableOfContent/TableOfContentAnchor.cjs.map +2 -2
  159. package/molecules/TableOfContent/TableOfContentAnchor.js +16 -0
  160. package/molecules/TableOfContent/TableOfContentAnchor.js.map +2 -2
  161. package/molecules/Tabs/Tabs.cjs +16 -0
  162. package/molecules/Tabs/Tabs.cjs.map +2 -2
  163. package/molecules/Tabs/Tabs.d.ts +3 -3
  164. package/molecules/Tabs/Tabs.js +16 -0
  165. package/molecules/Tabs/Tabs.js.map +2 -2
  166. package/organisms/Frame/Frame.cjs +30 -0
  167. package/organisms/Frame/Frame.cjs.map +2 -2
  168. package/organisms/Frame/Frame.js +30 -0
  169. package/organisms/Frame/Frame.js.map +2 -2
  170. package/organisms/Frame/FrameAnchor.cjs +6 -0
  171. package/organisms/Frame/FrameAnchor.cjs.map +1 -1
  172. package/organisms/Frame/FrameAnchor.js +6 -0
  173. package/organisms/Frame/FrameAnchor.js.map +1 -1
  174. package/organisms/Frame/FrameForm.cjs +6 -0
  175. package/organisms/Frame/FrameForm.cjs.map +1 -1
  176. package/organisms/Frame/FrameForm.js +6 -0
  177. package/organisms/Frame/FrameForm.js.map +1 -1
  178. package/organisms/Frame/FrameTarget.cjs +25 -2
  179. package/organisms/Frame/FrameTarget.cjs.map +2 -2
  180. package/organisms/Frame/FrameTarget.js +25 -2
  181. package/organisms/Frame/FrameTarget.js.map +2 -2
  182. package/organisms/Hero/Hero.twig +151 -0
  183. package/package.json +2 -2
  184. package/primitives/Draggable/Draggable.cjs +18 -0
  185. package/primitives/Draggable/Draggable.cjs.map +2 -2
  186. package/primitives/Draggable/Draggable.js +18 -0
  187. package/primitives/Draggable/Draggable.js.map +2 -2
  188. package/primitives/Sentinel/Sentinel.cjs +3 -0
  189. package/primitives/Sentinel/Sentinel.cjs.map +2 -2
  190. package/primitives/Sentinel/Sentinel.js +3 -0
  191. package/primitives/Sentinel/Sentinel.js.map +2 -2
  192. package/primitives/Transition/Transition.cjs +3 -0
  193. package/primitives/Transition/Transition.cjs.map +1 -1
  194. package/primitives/Transition/Transition.js +3 -0
  195. package/primitives/Transition/Transition.js.map +1 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../packages/ui/molecules/Tabs/Tabs.ts"],
4
- "sourcesContent": ["import { Base } from '@studiometa/js-toolkit';\nimport type { BaseProps, BaseConfig } from '@studiometa/js-toolkit';\nimport { transition } from '@studiometa/js-toolkit/utils';\n\ntype TabItem = {\n btn: HTMLElement;\n content: HTMLElement;\n isEnabled: boolean;\n};\n\ntype TabsStates = Partial<\n Record<'open' | 'active' | 'closed', string | Partial<CSSStyleDeclaration>>\n>;\n// eslint-disable-next-line no-use-before-define\ntype TabsStylesOption = Partial<Record<keyof TabsProps['$refs'], TabsStates>>;\n\nexport interface TabsProps extends BaseProps {\n $options: {\n styles: TabsStylesOption;\n };\n $refs: {\n btn: HTMLElement[];\n content: HTMLElement[];\n };\n}\n\n/**\n * Tabs class.\n */\nexport class Tabs<T extends BaseProps = BaseProps> extends Base<T & TabsProps> {\n /**\n * Config.\n */\n static config: BaseConfig = {\n name: 'Tabs',\n refs: ['btn[]', 'content[]'],\n emits: ['enable', 'disable'],\n options: {\n styles: {\n type: Object,\n default: (): TabsStylesOption => ({\n content: {\n closed: {\n position: 'absolute',\n opacity: '0',\n pointerEvents: 'none',\n visibility: 'hidden',\n },\n },\n }),\n merge: true,\n },\n },\n };\n\n items: TabItem[];\n\n /**\n * Initialize the component's behaviours.\n * @returns {void}\n */\n mounted() {\n this.items = this.$refs.btn.map((btn, index) => {\n const id = `${this.$id}-${index}`;\n const content = this.$refs.content[index];\n btn.setAttribute('id', id);\n content.setAttribute('aria-labelledby', id);\n\n const item = { btn, content, isEnabled: index > 0 };\n if (index > 0) {\n this.disableItem(item);\n } else {\n this.enableItem(item);\n }\n return item;\n });\n }\n\n /**\n * Switch tab on button click.\n */\n onBtnClick(event:MouseEvent, index:number) {\n this.items.forEach((item, i) => {\n if (i !== index) {\n this.disableItem(item);\n }\n });\n\n this.enableItem(this.items[index]);\n }\n\n /**\n * Enable the given tab and its associated content.\n */\n async enableItem(item:TabItem):Promise<this> {\n if (!item || item.isEnabled) {\n return Promise.resolve(this);\n }\n\n item.isEnabled = true;\n const { btn, content } = item;\n const btnStyles = this.$options.styles.btn || {};\n const contentStyles = this.$options.styles.content || {};\n\n content.setAttribute('aria-hidden', 'false');\n this.$emit('enable', item);\n\n return Promise.all([\n transition(\n btn,\n {\n from: btnStyles.closed,\n active: btnStyles.active,\n to: btnStyles.open,\n },\n 'keep',\n ),\n transition(\n content,\n {\n from: contentStyles.closed,\n active: contentStyles.active,\n to: contentStyles.open,\n },\n 'keep',\n ),\n ]).then(() => Promise.resolve(this));\n }\n\n /**\n * Disable the given tab and its associated content.\n */\n async disableItem(item:TabItem):Promise<this> {\n if (!item || !item.isEnabled) {\n return Promise.resolve(this);\n }\n\n item.isEnabled = false;\n const { btn, content } = item;\n const btnStyles = this.$options.styles.btn || {};\n const contentStyles = this.$options.styles.content || {};\n\n content.setAttribute('aria-hidden', 'true');\n this.$emit('disable', item);\n\n return Promise.all([\n transition(\n btn,\n {\n from: btnStyles.open,\n active: btnStyles.active,\n to: btnStyles.closed,\n },\n 'keep',\n ),\n transition(\n content,\n {\n from: contentStyles.open,\n active: contentStyles.active,\n to: contentStyles.closed,\n },\n 'keep',\n ),\n ]).then(() => Promise.resolve(this));\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Base } from '@studiometa/js-toolkit';\nimport type { BaseProps, BaseConfig } from '@studiometa/js-toolkit';\nimport { transition } from '@studiometa/js-toolkit/utils';\n\ntype TabItem = {\n btn: HTMLElement;\n content: HTMLElement;\n isEnabled: boolean;\n};\n\ntype TabsStates = Partial<\n Record<'open' | 'active' | 'closed', string | Partial<CSSStyleDeclaration>>\n>;\n// eslint-disable-next-line no-use-before-define\ntype TabsStylesOption = Partial<Record<keyof TabsProps['$refs'], TabsStates>>;\n\nexport interface TabsProps extends BaseProps {\n $options: {\n styles: TabsStylesOption;\n };\n $refs: {\n btn: HTMLElement[];\n content: HTMLElement[];\n };\n}\n\n/**\n * Tabs class.\n */\nexport class Tabs<T extends BaseProps = BaseProps> extends Base<T & TabsProps> {\n /**\n * Config.\n */\n static config: BaseConfig = {\n name: 'Tabs',\n refs: ['btn[]', 'content[]'],\n emits: ['enable', 'disable'],\n options: {\n styles: {\n type: Object,\n default: (): TabsStylesOption => ({\n content: {\n closed: {\n position: 'absolute',\n opacity: '0',\n pointerEvents: 'none',\n visibility: 'hidden',\n },\n },\n }),\n merge: true,\n },\n },\n };\n\n items: TabItem[];\n\n /**\n * Initialize the component's behaviours.\n * @returns {void}\n */\n mounted() {\n this.items = this.$refs.btn.map((btn, index) => {\n const id = `${this.$id}-${index}`;\n const content = this.$refs.content[index];\n btn.setAttribute('id', id);\n content.setAttribute('aria-labelledby', id);\n\n const item = { btn, content, isEnabled: index > 0 };\n if (index > 0) {\n this.disableItem(item);\n } else {\n this.enableItem(item);\n }\n return item;\n });\n }\n\n /**\n * Switch tab on button click.\n */\n onBtnClick(event: MouseEvent, index: number) {\n this.items.forEach((item, i) => {\n if (i !== index) {\n this.disableItem(item);\n }\n });\n\n this.enableItem(this.items[index]);\n }\n\n /**\n * Enable the given tab and its associated content.\n */\n async enableItem(item: TabItem): Promise<this> {\n if (!item || item.isEnabled) {\n return Promise.resolve(this);\n }\n\n item.isEnabled = true;\n const { btn, content } = item;\n const btnStyles = this.$options.styles.btn || {};\n const contentStyles = this.$options.styles.content || {};\n\n content.setAttribute('aria-hidden', 'false');\n this.$emit('enable', item);\n\n return Promise.all([\n transition(\n btn,\n {\n from: btnStyles.closed,\n active: btnStyles.active,\n to: btnStyles.open,\n },\n 'keep',\n ),\n transition(\n content,\n {\n from: contentStyles.closed,\n active: contentStyles.active,\n to: contentStyles.open,\n },\n 'keep',\n ),\n ]).then(() => Promise.resolve(this));\n }\n\n /**\n * Disable the given tab and its associated content.\n */\n async disableItem(item: TabItem): Promise<this> {\n if (!item || !item.isEnabled) {\n return Promise.resolve(this);\n }\n\n item.isEnabled = false;\n const { btn, content } = item;\n const btnStyles = this.$options.styles.btn || {};\n const contentStyles = this.$options.styles.content || {};\n\n content.setAttribute('aria-hidden', 'true');\n this.$emit('disable', item);\n\n return Promise.all([\n transition(\n btn,\n {\n from: btnStyles.open,\n active: btnStyles.active,\n to: btnStyles.closed,\n },\n 'keep',\n ),\n transition(\n content,\n {\n from: contentStyles.open,\n active: contentStyles.active,\n to: contentStyles.closed,\n },\n 'keep',\n ),\n ]).then(() => Promise.resolve(this));\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,12 +1,12 @@
1
1
  import { Base } from '@studiometa/js-toolkit';
2
2
  import type { BaseProps, BaseConfig } from '@studiometa/js-toolkit';
3
- declare type TabItem = {
3
+ type TabItem = {
4
4
  btn: HTMLElement;
5
5
  content: HTMLElement;
6
6
  isEnabled: boolean;
7
7
  };
8
- declare type TabsStates = Partial<Record<'open' | 'active' | 'closed', string | Partial<CSSStyleDeclaration>>>;
9
- declare type TabsStylesOption = Partial<Record<keyof TabsProps['$refs'], TabsStates>>;
8
+ type TabsStates = Partial<Record<'open' | 'active' | 'closed', string | Partial<CSSStyleDeclaration>>>;
9
+ type TabsStylesOption = Partial<Record<keyof TabsProps['$refs'], TabsStates>>;
10
10
  export interface TabsProps extends BaseProps {
11
11
  $options: {
12
12
  styles: TabsStylesOption;
@@ -1,6 +1,9 @@
1
1
  import { Base } from "@studiometa/js-toolkit";
2
2
  import { transition } from "@studiometa/js-toolkit/utils";
3
3
  class Tabs extends Base {
4
+ /**
5
+ * Config.
6
+ */
4
7
  static config = {
5
8
  name: "Tabs",
6
9
  refs: ["btn[]", "content[]"],
@@ -23,6 +26,10 @@ class Tabs extends Base {
23
26
  }
24
27
  };
25
28
  items;
29
+ /**
30
+ * Initialize the component's behaviours.
31
+ * @returns {void}
32
+ */
26
33
  mounted() {
27
34
  this.items = this.$refs.btn.map((btn, index) => {
28
35
  const id = `${this.$id}-${index}`;
@@ -38,6 +45,9 @@ class Tabs extends Base {
38
45
  return item;
39
46
  });
40
47
  }
48
+ /**
49
+ * Switch tab on button click.
50
+ */
41
51
  onBtnClick(event, index) {
42
52
  this.items.forEach((item, i) => {
43
53
  if (i !== index) {
@@ -46,6 +56,9 @@ class Tabs extends Base {
46
56
  });
47
57
  this.enableItem(this.items[index]);
48
58
  }
59
+ /**
60
+ * Enable the given tab and its associated content.
61
+ */
49
62
  async enableItem(item) {
50
63
  if (!item || item.isEnabled) {
51
64
  return Promise.resolve(this);
@@ -77,6 +90,9 @@ class Tabs extends Base {
77
90
  )
78
91
  ]).then(() => Promise.resolve(this));
79
92
  }
93
+ /**
94
+ * Disable the given tab and its associated content.
95
+ */
80
96
  async disableItem(item) {
81
97
  if (!item || !item.isEnabled) {
82
98
  return Promise.resolve(this);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../packages/ui/molecules/Tabs/Tabs.ts"],
4
- "sourcesContent": ["import { Base } from '@studiometa/js-toolkit';\nimport type { BaseProps, BaseConfig } from '@studiometa/js-toolkit';\nimport { transition } from '@studiometa/js-toolkit/utils';\n\ntype TabItem = {\n btn: HTMLElement;\n content: HTMLElement;\n isEnabled: boolean;\n};\n\ntype TabsStates = Partial<\n Record<'open' | 'active' | 'closed', string | Partial<CSSStyleDeclaration>>\n>;\n// eslint-disable-next-line no-use-before-define\ntype TabsStylesOption = Partial<Record<keyof TabsProps['$refs'], TabsStates>>;\n\nexport interface TabsProps extends BaseProps {\n $options: {\n styles: TabsStylesOption;\n };\n $refs: {\n btn: HTMLElement[];\n content: HTMLElement[];\n };\n}\n\n/**\n * Tabs class.\n */\nexport class Tabs<T extends BaseProps = BaseProps> extends Base<T & TabsProps> {\n /**\n * Config.\n */\n static config: BaseConfig = {\n name: 'Tabs',\n refs: ['btn[]', 'content[]'],\n emits: ['enable', 'disable'],\n options: {\n styles: {\n type: Object,\n default: (): TabsStylesOption => ({\n content: {\n closed: {\n position: 'absolute',\n opacity: '0',\n pointerEvents: 'none',\n visibility: 'hidden',\n },\n },\n }),\n merge: true,\n },\n },\n };\n\n items: TabItem[];\n\n /**\n * Initialize the component's behaviours.\n * @returns {void}\n */\n mounted() {\n this.items = this.$refs.btn.map((btn, index) => {\n const id = `${this.$id}-${index}`;\n const content = this.$refs.content[index];\n btn.setAttribute('id', id);\n content.setAttribute('aria-labelledby', id);\n\n const item = { btn, content, isEnabled: index > 0 };\n if (index > 0) {\n this.disableItem(item);\n } else {\n this.enableItem(item);\n }\n return item;\n });\n }\n\n /**\n * Switch tab on button click.\n */\n onBtnClick(event:MouseEvent, index:number) {\n this.items.forEach((item, i) => {\n if (i !== index) {\n this.disableItem(item);\n }\n });\n\n this.enableItem(this.items[index]);\n }\n\n /**\n * Enable the given tab and its associated content.\n */\n async enableItem(item:TabItem):Promise<this> {\n if (!item || item.isEnabled) {\n return Promise.resolve(this);\n }\n\n item.isEnabled = true;\n const { btn, content } = item;\n const btnStyles = this.$options.styles.btn || {};\n const contentStyles = this.$options.styles.content || {};\n\n content.setAttribute('aria-hidden', 'false');\n this.$emit('enable', item);\n\n return Promise.all([\n transition(\n btn,\n {\n from: btnStyles.closed,\n active: btnStyles.active,\n to: btnStyles.open,\n },\n 'keep',\n ),\n transition(\n content,\n {\n from: contentStyles.closed,\n active: contentStyles.active,\n to: contentStyles.open,\n },\n 'keep',\n ),\n ]).then(() => Promise.resolve(this));\n }\n\n /**\n * Disable the given tab and its associated content.\n */\n async disableItem(item:TabItem):Promise<this> {\n if (!item || !item.isEnabled) {\n return Promise.resolve(this);\n }\n\n item.isEnabled = false;\n const { btn, content } = item;\n const btnStyles = this.$options.styles.btn || {};\n const contentStyles = this.$options.styles.content || {};\n\n content.setAttribute('aria-hidden', 'true');\n this.$emit('disable', item);\n\n return Promise.all([\n transition(\n btn,\n {\n from: btnStyles.open,\n active: btnStyles.active,\n to: btnStyles.closed,\n },\n 'keep',\n ),\n transition(\n content,\n {\n from: contentStyles.open,\n active: contentStyles.active,\n to: contentStyles.closed,\n },\n 'keep',\n ),\n ]).then(() => Promise.resolve(this));\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Base } from '@studiometa/js-toolkit';\nimport type { BaseProps, BaseConfig } from '@studiometa/js-toolkit';\nimport { transition } from '@studiometa/js-toolkit/utils';\n\ntype TabItem = {\n btn: HTMLElement;\n content: HTMLElement;\n isEnabled: boolean;\n};\n\ntype TabsStates = Partial<\n Record<'open' | 'active' | 'closed', string | Partial<CSSStyleDeclaration>>\n>;\n// eslint-disable-next-line no-use-before-define\ntype TabsStylesOption = Partial<Record<keyof TabsProps['$refs'], TabsStates>>;\n\nexport interface TabsProps extends BaseProps {\n $options: {\n styles: TabsStylesOption;\n };\n $refs: {\n btn: HTMLElement[];\n content: HTMLElement[];\n };\n}\n\n/**\n * Tabs class.\n */\nexport class Tabs<T extends BaseProps = BaseProps> extends Base<T & TabsProps> {\n /**\n * Config.\n */\n static config: BaseConfig = {\n name: 'Tabs',\n refs: ['btn[]', 'content[]'],\n emits: ['enable', 'disable'],\n options: {\n styles: {\n type: Object,\n default: (): TabsStylesOption => ({\n content: {\n closed: {\n position: 'absolute',\n opacity: '0',\n pointerEvents: 'none',\n visibility: 'hidden',\n },\n },\n }),\n merge: true,\n },\n },\n };\n\n items: TabItem[];\n\n /**\n * Initialize the component's behaviours.\n * @returns {void}\n */\n mounted() {\n this.items = this.$refs.btn.map((btn, index) => {\n const id = `${this.$id}-${index}`;\n const content = this.$refs.content[index];\n btn.setAttribute('id', id);\n content.setAttribute('aria-labelledby', id);\n\n const item = { btn, content, isEnabled: index > 0 };\n if (index > 0) {\n this.disableItem(item);\n } else {\n this.enableItem(item);\n }\n return item;\n });\n }\n\n /**\n * Switch tab on button click.\n */\n onBtnClick(event: MouseEvent, index: number) {\n this.items.forEach((item, i) => {\n if (i !== index) {\n this.disableItem(item);\n }\n });\n\n this.enableItem(this.items[index]);\n }\n\n /**\n * Enable the given tab and its associated content.\n */\n async enableItem(item: TabItem): Promise<this> {\n if (!item || item.isEnabled) {\n return Promise.resolve(this);\n }\n\n item.isEnabled = true;\n const { btn, content } = item;\n const btnStyles = this.$options.styles.btn || {};\n const contentStyles = this.$options.styles.content || {};\n\n content.setAttribute('aria-hidden', 'false');\n this.$emit('enable', item);\n\n return Promise.all([\n transition(\n btn,\n {\n from: btnStyles.closed,\n active: btnStyles.active,\n to: btnStyles.open,\n },\n 'keep',\n ),\n transition(\n content,\n {\n from: contentStyles.closed,\n active: contentStyles.active,\n to: contentStyles.open,\n },\n 'keep',\n ),\n ]).then(() => Promise.resolve(this));\n }\n\n /**\n * Disable the given tab and its associated content.\n */\n async disableItem(item: TabItem): Promise<this> {\n if (!item || !item.isEnabled) {\n return Promise.resolve(this);\n }\n\n item.isEnabled = false;\n const { btn, content } = item;\n const btnStyles = this.$options.styles.btn || {};\n const contentStyles = this.$options.styles.content || {};\n\n content.setAttribute('aria-hidden', 'true');\n this.$emit('disable', item);\n\n return Promise.all([\n transition(\n btn,\n {\n from: btnStyles.open,\n active: btnStyles.active,\n to: btnStyles.closed,\n },\n 'keep',\n ),\n transition(\n content,\n {\n from: contentStyles.open,\n active: contentStyles.active,\n to: contentStyles.closed,\n },\n 'keep',\n ),\n ]).then(() => Promise.resolve(this));\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -40,12 +40,21 @@ function getScrollPosition() {
40
40
  }
41
41
  var cache = /* @__PURE__ */ new Map();
42
42
  var _Frame = class extends import_js_toolkit.Base {
43
+ /**
44
+ * Get uniq id.
45
+ */
43
46
  get id() {
44
47
  return this.$el.id;
45
48
  }
49
+ /**
50
+ * Get direct `FrameTarget` children.
51
+ */
46
52
  get directChildrenFrameTarget() {
47
53
  return (0, import_js_toolkit.getDirectChildren)(this, "Frame", "FrameTarget");
48
54
  }
55
+ /**
56
+ * Prevent scroll top on unload.
57
+ */
49
58
  onWindowUnload() {
50
59
  const { history } = window;
51
60
  if (!history.state) {
@@ -59,9 +68,15 @@ var _Frame = class extends import_js_toolkit.Base {
59
68
  ""
60
69
  );
61
70
  }
71
+ /**
72
+ * Go to the previous URL on `popstate` event.
73
+ */
62
74
  onWindowPopstate(event) {
63
75
  this.goTo(window.location.href, event.state);
64
76
  }
77
+ /**
78
+ * Prevent click on `FrameAnchor`.
79
+ */
65
80
  onFrameAnchorClick(index, event) {
66
81
  if (!(0, import_js_toolkit.isDirectChild)(this, "Frame", "FrameAnchor", this.$children.FrameAnchor[index])) {
67
82
  return;
@@ -74,6 +89,9 @@ var _Frame = class extends import_js_toolkit.Base {
74
89
  }
75
90
  this.goTo(anchor.href);
76
91
  }
92
+ /**
93
+ * Prevent submit on forms.
94
+ */
77
95
  onFrameFormSubmit(index, event) {
78
96
  if (!(0, import_js_toolkit.isDirectChild)(this, "Frame", "FrameForm", this.$children.FrameForm[index])) {
79
97
  return;
@@ -85,9 +103,15 @@ var _Frame = class extends import_js_toolkit.Base {
85
103
  url.search = new URLSearchParams(new FormData(form.$el)).toString();
86
104
  this.goTo(url.toString());
87
105
  }
106
+ /**
107
+ * Parge an HTML string into a DOM object.
108
+ */
88
109
  parseHTML(string = "") {
89
110
  return new DOMParser().parseFromString(string, "text/html");
90
111
  }
112
+ /**
113
+ * Go to the given url.
114
+ */
91
115
  async goTo(url, scroll = null) {
92
116
  this.$log("goTo", url);
93
117
  const parsedUrl = new URL(url);
@@ -124,6 +148,9 @@ var _Frame = class extends import_js_toolkit.Base {
124
148
  await Promise.all(this.directChildrenFrameTarget.map((target) => target.enter()));
125
149
  this.$emit("after-enter");
126
150
  }
151
+ /**
152
+ * Fetch the given url.
153
+ */
127
154
  async fetch(url) {
128
155
  const cached = cache.get(url);
129
156
  if (cached) {
@@ -157,6 +184,9 @@ var _Frame = class extends import_js_toolkit.Base {
157
184
  }
158
185
  };
159
186
  var Frame = _Frame;
187
+ /**
188
+ * Config.
189
+ */
160
190
  __publicField(Frame, "config", {
161
191
  name: "Frame",
162
192
  emits: [
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../packages/ui/organisms/Frame/Frame.ts"],
4
- "sourcesContent": ["import { Base, isDirectChild, getDirectChildren } from '@studiometa/js-toolkit';\nimport type { BaseProps, BaseConfig } from '@studiometa/js-toolkit';\nimport { nextFrame, historyPush } from '@studiometa/js-toolkit/utils';\nimport { FrameAnchor } from './FrameAnchor.js';\nimport { FrameForm } from './FrameForm.js';\nimport { FrameTarget } from './FrameTarget.js';\n\n/**\n * Get the scroll position.\n */\nfunction getScrollPosition() {\n return {\n left: window.pageXOffset,\n top: window.pageYOffset,\n };\n}\n\n/**\n * The fetch cache.\n */\nconst cache: Map<\n string,\n { promise: Promise<string>; status: 'pending' | 'resolved' | 'error'; content: string }\n> = new Map();\n\nexport interface FrameProps extends BaseProps {\n $children: {\n FrameAnchor: FrameAnchor[];\n FrameForm: FrameForm[];\n FrameTarget: FrameTarget[];\n // eslint-disable-next-line no-use-before-define\n Frame: Frame[];\n };\n $options: {\n history: boolean;\n };\n}\n\n/**\n * Class.\n */\nexport class Frame<T extends BaseProps = BaseProps> extends Base<T & FrameProps> {\n /**\n * Config.\n */\n static config: BaseConfig = {\n name: 'Frame',\n emits: [\n 'before-fetch',\n 'after-fetch',\n 'before-leave',\n 'after-leave',\n 'before-content',\n 'after-content',\n 'before-enter',\n 'after-enter',\n ],\n components: {\n FrameAnchor,\n FrameForm,\n FrameTarget,\n Frame,\n },\n options: {\n history: Boolean,\n },\n };\n\n /**\n * Get uniq id.\n */\n get id() {\n return this.$el.id;\n }\n\n /**\n * Get direct `FrameTarget` children.\n */\n get directChildrenFrameTarget(): FrameTarget[] {\n return getDirectChildren(this, 'Frame', 'FrameTarget');\n }\n\n /**\n * Prevent scroll top on unload.\n */\n onWindowUnload() {\n const { history } = window;\n\n if (!history.state) {\n return;\n }\n\n history.replaceState(\n {\n ...history.state,\n scroll: getScrollPosition(),\n },\n '',\n );\n }\n\n /**\n * Go to the previous URL on `popstate` event.\n */\n onWindowPopstate(event: PopStateEvent) {\n this.goTo(window.location.href, event.state);\n }\n\n /**\n * Prevent click on `FrameAnchor`.\n */\n onFrameAnchorClick(index: number, event: MouseEvent) {\n // Prevent propagation of nested frames\n if (!isDirectChild(this, 'Frame', 'FrameAnchor', this.$children.FrameAnchor[index])) {\n return;\n }\n\n this.$log('onAFrameClick', index, event);\n event.preventDefault();\n const anchor = this.$children.FrameAnchor[index];\n\n // Do nothing when clicking links on the same page\n // @todo handle hash change\n if (anchor.href === window.location.href) {\n return;\n }\n\n this.goTo(anchor.href);\n }\n\n /**\n * Prevent submit on forms.\n */\n onFrameFormSubmit(index:number, event:SubmitEvent) {\n // Prevent propagation of nested frames\n if (!isDirectChild(this, 'Frame', 'FrameForm', this.$children.FrameForm[index])) {\n return;\n }\n\n this.$log('onFrameFormFrameSubmit', index, event);\n event.preventDefault();\n const form = this.$children.FrameForm[index];\n const url = new URL(form.action);\n // @ts-ignore\n url.search = new URLSearchParams(new FormData(form.$el)).toString();\n // @todo handle post request\n this.goTo(url.toString());\n }\n\n /**\n * Parge an HTML string into a DOM object.\n */\n parseHTML(string = '') {\n return new DOMParser().parseFromString(string, 'text/html');\n }\n\n /**\n * Go to the given url.\n */\n async goTo(url:string, scroll:{ top: number, left: number } = null) {\n this.$log('goTo', url);\n const parsedUrl = new URL(url);\n\n if (parsedUrl.origin !== window.location.origin) {\n throw new Error('Cross origin request are not allowed.');\n }\n\n this.$emit('before-fetch', url);\n\n // @todo add option to use content as is or to parse it and extract the new frame\n const content = await this.fetch(url);\n const doc = this.parseHTML(content);\n const el = doc.querySelector(`#${this.id}`);\n // @todo manage el === null\n const newFrame = new Frame(el as HTMLElement);\n newFrame.$children.registerAll();\n\n this.$emit('after-fetch', url, content);\n\n this.$emit('before-leave');\n // Leave all\n await Promise.all(this.directChildrenFrameTarget.map((target) => target.leave()));\n\n this.$emit('after-leave');\n this.$emit('before-content');\n\n // Update content\n // @todo insert non existing FrameTarget as well\n this.directChildrenFrameTarget.map((target, index) =>\n target.updateContent(newFrame.directChildrenFrameTarget[index]),\n );\n\n // Push history\n if (this.$options.history) {\n document.title = doc.title;\n historyPush({ path: parsedUrl.pathname, search: parsedUrl.searchParams });\n }\n\n if (scroll) {\n document.scrollingElement.scrollTop = scroll.top;\n document.scrollingElement.scrollLeft = scroll.left;\n }\n\n // Update components\n await nextFrame();\n this.$root.$update();\n await nextFrame();\n\n this.$emit('after-content');\n this.$emit('before-enter');\n\n // Enter all\n await Promise.all(this.directChildrenFrameTarget.map((target) => target.enter()));\n\n this.$emit('after-enter');\n }\n\n /**\n * Fetch the given url.\n */\n async fetch(url:string):Promise<string> {\n const cached = cache.get(url);\n\n if (cached) {\n if (cached.status === 'pending') {\n return cached.promise;\n }\n\n return cached.content;\n }\n\n const promise = fetch(url).then((response) => response.text());\n\n try {\n cache.set(url, {\n promise,\n status: 'pending',\n content: undefined,\n });\n\n const content = await promise;\n\n cache.set(url, {\n promise,\n status: 'resolved',\n content,\n });\n\n return content;\n } catch (err) {\n cache.set(url, {\n promise,\n status: 'error',\n content: err,\n });\n\n return err;\n }\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Base, isDirectChild, getDirectChildren } from '@studiometa/js-toolkit';\nimport type { BaseProps, BaseConfig } from '@studiometa/js-toolkit';\nimport { nextFrame, historyPush } from '@studiometa/js-toolkit/utils';\nimport { FrameAnchor } from './FrameAnchor.js';\nimport { FrameForm } from './FrameForm.js';\nimport { FrameTarget } from './FrameTarget.js';\n\n/**\n * Get the scroll position.\n */\nfunction getScrollPosition() {\n return {\n left: window.pageXOffset,\n top: window.pageYOffset,\n };\n}\n\n/**\n * The fetch cache.\n */\nconst cache: Map<\n string,\n { promise: Promise<string>; status: 'pending' | 'resolved' | 'error'; content: string }\n> = new Map();\n\nexport interface FrameProps extends BaseProps {\n $children: {\n FrameAnchor: FrameAnchor[];\n FrameForm: FrameForm[];\n FrameTarget: FrameTarget[];\n // eslint-disable-next-line no-use-before-define\n Frame: Frame[];\n };\n $options: {\n history: boolean;\n };\n}\n\n/**\n * Class.\n */\nexport class Frame<T extends BaseProps = BaseProps> extends Base<T & FrameProps> {\n /**\n * Config.\n */\n static config: BaseConfig = {\n name: 'Frame',\n emits: [\n 'before-fetch',\n 'after-fetch',\n 'before-leave',\n 'after-leave',\n 'before-content',\n 'after-content',\n 'before-enter',\n 'after-enter',\n ],\n components: {\n FrameAnchor,\n FrameForm,\n FrameTarget,\n Frame,\n },\n options: {\n history: Boolean,\n },\n };\n\n /**\n * Get uniq id.\n */\n get id() {\n return this.$el.id;\n }\n\n /**\n * Get direct `FrameTarget` children.\n */\n get directChildrenFrameTarget(): FrameTarget[] {\n return getDirectChildren(this, 'Frame', 'FrameTarget');\n }\n\n /**\n * Prevent scroll top on unload.\n */\n onWindowUnload() {\n const { history } = window;\n\n if (!history.state) {\n return;\n }\n\n history.replaceState(\n {\n ...history.state,\n scroll: getScrollPosition(),\n },\n '',\n );\n }\n\n /**\n * Go to the previous URL on `popstate` event.\n */\n onWindowPopstate(event: PopStateEvent) {\n this.goTo(window.location.href, event.state);\n }\n\n /**\n * Prevent click on `FrameAnchor`.\n */\n onFrameAnchorClick(index: number, event: MouseEvent) {\n // Prevent propagation of nested frames\n if (!isDirectChild(this, 'Frame', 'FrameAnchor', this.$children.FrameAnchor[index])) {\n return;\n }\n\n this.$log('onAFrameClick', index, event);\n event.preventDefault();\n const anchor = this.$children.FrameAnchor[index];\n\n // Do nothing when clicking links on the same page\n // @todo handle hash change\n if (anchor.href === window.location.href) {\n return;\n }\n\n this.goTo(anchor.href);\n }\n\n /**\n * Prevent submit on forms.\n */\n onFrameFormSubmit(index: number, event: SubmitEvent) {\n // Prevent propagation of nested frames\n if (!isDirectChild(this, 'Frame', 'FrameForm', this.$children.FrameForm[index])) {\n return;\n }\n\n this.$log('onFrameFormFrameSubmit', index, event);\n event.preventDefault();\n const form = this.$children.FrameForm[index];\n const url = new URL(form.action);\n // @ts-ignore\n url.search = new URLSearchParams(new FormData(form.$el)).toString();\n // @todo handle post request\n this.goTo(url.toString());\n }\n\n /**\n * Parge an HTML string into a DOM object.\n */\n parseHTML(string = '') {\n return new DOMParser().parseFromString(string, 'text/html');\n }\n\n /**\n * Go to the given url.\n */\n async goTo(url: string, scroll: { top: number; left: number } = null) {\n this.$log('goTo', url);\n const parsedUrl = new URL(url);\n\n if (parsedUrl.origin !== window.location.origin) {\n throw new Error('Cross origin request are not allowed.');\n }\n\n this.$emit('before-fetch', url);\n\n // @todo add option to use content as is or to parse it and extract the new frame\n const content = await this.fetch(url);\n const doc = this.parseHTML(content);\n const el = doc.querySelector(`#${this.id}`);\n // @todo manage el === null\n const newFrame = new Frame(el as HTMLElement);\n newFrame.$children.registerAll();\n\n this.$emit('after-fetch', url, content);\n\n this.$emit('before-leave');\n // Leave all\n await Promise.all(this.directChildrenFrameTarget.map((target) => target.leave()));\n\n this.$emit('after-leave');\n this.$emit('before-content');\n\n // Update content\n // @todo insert non existing FrameTarget as well\n this.directChildrenFrameTarget.map((target, index) =>\n target.updateContent(newFrame.directChildrenFrameTarget[index]),\n );\n\n // Push history\n if (this.$options.history) {\n document.title = doc.title;\n historyPush({ path: parsedUrl.pathname, search: parsedUrl.searchParams });\n }\n\n if (scroll) {\n document.scrollingElement.scrollTop = scroll.top;\n document.scrollingElement.scrollLeft = scroll.left;\n }\n\n // Update components\n await nextFrame();\n this.$root.$update();\n await nextFrame();\n\n this.$emit('after-content');\n this.$emit('before-enter');\n\n // Enter all\n await Promise.all(this.directChildrenFrameTarget.map((target) => target.enter()));\n\n this.$emit('after-enter');\n }\n\n /**\n * Fetch the given url.\n */\n async fetch(url: string): Promise<string> {\n const cached = cache.get(url);\n\n if (cached) {\n if (cached.status === 'pending') {\n return cached.promise;\n }\n\n return cached.content;\n }\n\n const promise = fetch(url).then((response) => response.text());\n\n try {\n cache.set(url, {\n promise,\n status: 'pending',\n content: undefined,\n });\n\n const content = await promise;\n\n cache.set(url, {\n promise,\n status: 'resolved',\n content,\n });\n\n return content;\n } catch (err) {\n cache.set(url, {\n promise,\n status: 'error',\n content: err,\n });\n\n return err;\n }\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -11,6 +11,9 @@ function getScrollPosition() {
11
11
  }
12
12
  const cache = /* @__PURE__ */ new Map();
13
13
  class Frame extends Base {
14
+ /**
15
+ * Config.
16
+ */
14
17
  static config = {
15
18
  name: "Frame",
16
19
  emits: [
@@ -33,12 +36,21 @@ class Frame extends Base {
33
36
  history: Boolean
34
37
  }
35
38
  };
39
+ /**
40
+ * Get uniq id.
41
+ */
36
42
  get id() {
37
43
  return this.$el.id;
38
44
  }
45
+ /**
46
+ * Get direct `FrameTarget` children.
47
+ */
39
48
  get directChildrenFrameTarget() {
40
49
  return getDirectChildren(this, "Frame", "FrameTarget");
41
50
  }
51
+ /**
52
+ * Prevent scroll top on unload.
53
+ */
42
54
  onWindowUnload() {
43
55
  const { history } = window;
44
56
  if (!history.state) {
@@ -52,9 +64,15 @@ class Frame extends Base {
52
64
  ""
53
65
  );
54
66
  }
67
+ /**
68
+ * Go to the previous URL on `popstate` event.
69
+ */
55
70
  onWindowPopstate(event) {
56
71
  this.goTo(window.location.href, event.state);
57
72
  }
73
+ /**
74
+ * Prevent click on `FrameAnchor`.
75
+ */
58
76
  onFrameAnchorClick(index, event) {
59
77
  if (!isDirectChild(this, "Frame", "FrameAnchor", this.$children.FrameAnchor[index])) {
60
78
  return;
@@ -67,6 +85,9 @@ class Frame extends Base {
67
85
  }
68
86
  this.goTo(anchor.href);
69
87
  }
88
+ /**
89
+ * Prevent submit on forms.
90
+ */
70
91
  onFrameFormSubmit(index, event) {
71
92
  if (!isDirectChild(this, "Frame", "FrameForm", this.$children.FrameForm[index])) {
72
93
  return;
@@ -78,9 +99,15 @@ class Frame extends Base {
78
99
  url.search = new URLSearchParams(new FormData(form.$el)).toString();
79
100
  this.goTo(url.toString());
80
101
  }
102
+ /**
103
+ * Parge an HTML string into a DOM object.
104
+ */
81
105
  parseHTML(string = "") {
82
106
  return new DOMParser().parseFromString(string, "text/html");
83
107
  }
108
+ /**
109
+ * Go to the given url.
110
+ */
84
111
  async goTo(url, scroll = null) {
85
112
  this.$log("goTo", url);
86
113
  const parsedUrl = new URL(url);
@@ -117,6 +144,9 @@ class Frame extends Base {
117
144
  await Promise.all(this.directChildrenFrameTarget.map((target) => target.enter()));
118
145
  this.$emit("after-enter");
119
146
  }
147
+ /**
148
+ * Fetch the given url.
149
+ */
120
150
  async fetch(url) {
121
151
  const cached = cache.get(url);
122
152
  if (cached) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../packages/ui/organisms/Frame/Frame.ts"],
4
- "sourcesContent": ["import { Base, isDirectChild, getDirectChildren } from '@studiometa/js-toolkit';\nimport type { BaseProps, BaseConfig } from '@studiometa/js-toolkit';\nimport { nextFrame, historyPush } from '@studiometa/js-toolkit/utils';\nimport { FrameAnchor } from './FrameAnchor.js';\nimport { FrameForm } from './FrameForm.js';\nimport { FrameTarget } from './FrameTarget.js';\n\n/**\n * Get the scroll position.\n */\nfunction getScrollPosition() {\n return {\n left: window.pageXOffset,\n top: window.pageYOffset,\n };\n}\n\n/**\n * The fetch cache.\n */\nconst cache: Map<\n string,\n { promise: Promise<string>; status: 'pending' | 'resolved' | 'error'; content: string }\n> = new Map();\n\nexport interface FrameProps extends BaseProps {\n $children: {\n FrameAnchor: FrameAnchor[];\n FrameForm: FrameForm[];\n FrameTarget: FrameTarget[];\n // eslint-disable-next-line no-use-before-define\n Frame: Frame[];\n };\n $options: {\n history: boolean;\n };\n}\n\n/**\n * Class.\n */\nexport class Frame<T extends BaseProps = BaseProps> extends Base<T & FrameProps> {\n /**\n * Config.\n */\n static config: BaseConfig = {\n name: 'Frame',\n emits: [\n 'before-fetch',\n 'after-fetch',\n 'before-leave',\n 'after-leave',\n 'before-content',\n 'after-content',\n 'before-enter',\n 'after-enter',\n ],\n components: {\n FrameAnchor,\n FrameForm,\n FrameTarget,\n Frame,\n },\n options: {\n history: Boolean,\n },\n };\n\n /**\n * Get uniq id.\n */\n get id() {\n return this.$el.id;\n }\n\n /**\n * Get direct `FrameTarget` children.\n */\n get directChildrenFrameTarget(): FrameTarget[] {\n return getDirectChildren(this, 'Frame', 'FrameTarget');\n }\n\n /**\n * Prevent scroll top on unload.\n */\n onWindowUnload() {\n const { history } = window;\n\n if (!history.state) {\n return;\n }\n\n history.replaceState(\n {\n ...history.state,\n scroll: getScrollPosition(),\n },\n '',\n );\n }\n\n /**\n * Go to the previous URL on `popstate` event.\n */\n onWindowPopstate(event: PopStateEvent) {\n this.goTo(window.location.href, event.state);\n }\n\n /**\n * Prevent click on `FrameAnchor`.\n */\n onFrameAnchorClick(index: number, event: MouseEvent) {\n // Prevent propagation of nested frames\n if (!isDirectChild(this, 'Frame', 'FrameAnchor', this.$children.FrameAnchor[index])) {\n return;\n }\n\n this.$log('onAFrameClick', index, event);\n event.preventDefault();\n const anchor = this.$children.FrameAnchor[index];\n\n // Do nothing when clicking links on the same page\n // @todo handle hash change\n if (anchor.href === window.location.href) {\n return;\n }\n\n this.goTo(anchor.href);\n }\n\n /**\n * Prevent submit on forms.\n */\n onFrameFormSubmit(index:number, event:SubmitEvent) {\n // Prevent propagation of nested frames\n if (!isDirectChild(this, 'Frame', 'FrameForm', this.$children.FrameForm[index])) {\n return;\n }\n\n this.$log('onFrameFormFrameSubmit', index, event);\n event.preventDefault();\n const form = this.$children.FrameForm[index];\n const url = new URL(form.action);\n // @ts-ignore\n url.search = new URLSearchParams(new FormData(form.$el)).toString();\n // @todo handle post request\n this.goTo(url.toString());\n }\n\n /**\n * Parge an HTML string into a DOM object.\n */\n parseHTML(string = '') {\n return new DOMParser().parseFromString(string, 'text/html');\n }\n\n /**\n * Go to the given url.\n */\n async goTo(url:string, scroll:{ top: number, left: number } = null) {\n this.$log('goTo', url);\n const parsedUrl = new URL(url);\n\n if (parsedUrl.origin !== window.location.origin) {\n throw new Error('Cross origin request are not allowed.');\n }\n\n this.$emit('before-fetch', url);\n\n // @todo add option to use content as is or to parse it and extract the new frame\n const content = await this.fetch(url);\n const doc = this.parseHTML(content);\n const el = doc.querySelector(`#${this.id}`);\n // @todo manage el === null\n const newFrame = new Frame(el as HTMLElement);\n newFrame.$children.registerAll();\n\n this.$emit('after-fetch', url, content);\n\n this.$emit('before-leave');\n // Leave all\n await Promise.all(this.directChildrenFrameTarget.map((target) => target.leave()));\n\n this.$emit('after-leave');\n this.$emit('before-content');\n\n // Update content\n // @todo insert non existing FrameTarget as well\n this.directChildrenFrameTarget.map((target, index) =>\n target.updateContent(newFrame.directChildrenFrameTarget[index]),\n );\n\n // Push history\n if (this.$options.history) {\n document.title = doc.title;\n historyPush({ path: parsedUrl.pathname, search: parsedUrl.searchParams });\n }\n\n if (scroll) {\n document.scrollingElement.scrollTop = scroll.top;\n document.scrollingElement.scrollLeft = scroll.left;\n }\n\n // Update components\n await nextFrame();\n this.$root.$update();\n await nextFrame();\n\n this.$emit('after-content');\n this.$emit('before-enter');\n\n // Enter all\n await Promise.all(this.directChildrenFrameTarget.map((target) => target.enter()));\n\n this.$emit('after-enter');\n }\n\n /**\n * Fetch the given url.\n */\n async fetch(url:string):Promise<string> {\n const cached = cache.get(url);\n\n if (cached) {\n if (cached.status === 'pending') {\n return cached.promise;\n }\n\n return cached.content;\n }\n\n const promise = fetch(url).then((response) => response.text());\n\n try {\n cache.set(url, {\n promise,\n status: 'pending',\n content: undefined,\n });\n\n const content = await promise;\n\n cache.set(url, {\n promise,\n status: 'resolved',\n content,\n });\n\n return content;\n } catch (err) {\n cache.set(url, {\n promise,\n status: 'error',\n content: err,\n });\n\n return err;\n }\n }\n}\n"],
5
- "mappings": "AAAA,SAAS,MAAM,eAAe,yBAAyB;AAEvD,SAAS,WAAW,mBAAmB;AACvC,SAAS,mBAAmB;AAC5B,SAAS,iBAAiB;AAC1B,SAAS,mBAAmB;AAK5B,SAAS,oBAAoB;AAC3B,SAAO;AAAA,IACL,MAAM,OAAO;AAAA,IACb,KAAK,OAAO;AAAA,EACd;AACF;AAKA,MAAM,QAGF,oBAAI,IAAI;AAkBL,MAAM,cAA+C,KAAqB;AAAA,EAI/E,OAAO,SAAqB;AAAA,IAC1B,MAAM;AAAA,IACN,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,YAAY;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EAKA,IAAI,KAAK;AACP,WAAO,KAAK,IAAI;AAAA,EAClB;AAAA,EAKA,IAAI,4BAA2C;AAC7C,WAAO,kBAAkB,MAAM,SAAS,aAAa;AAAA,EACvD;AAAA,EAKA,iBAAiB;AACf,UAAM,EAAE,QAAQ,IAAI;AAEpB,QAAI,CAAC,QAAQ,OAAO;AAClB;AAAA,IACF;AAEA,YAAQ;AAAA,MACN;AAAA,QACE,GAAG,QAAQ;AAAA,QACX,QAAQ,kBAAkB;AAAA,MAC5B;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAKA,iBAAiB,OAAsB;AACrC,SAAK,KAAK,OAAO,SAAS,MAAM,MAAM,KAAK;AAAA,EAC7C;AAAA,EAKA,mBAAmB,OAAe,OAAmB;AAEnD,QAAI,CAAC,cAAc,MAAM,SAAS,eAAe,KAAK,UAAU,YAAY,MAAM,GAAG;AACnF;AAAA,IACF;AAEA,SAAK,KAAK,iBAAiB,OAAO,KAAK;AACvC,UAAM,eAAe;AACrB,UAAM,SAAS,KAAK,UAAU,YAAY;AAI1C,QAAI,OAAO,SAAS,OAAO,SAAS,MAAM;AACxC;AAAA,IACF;AAEA,SAAK,KAAK,OAAO,IAAI;AAAA,EACvB;AAAA,EAKA,kBAAkB,OAAc,OAAmB;AAEjD,QAAI,CAAC,cAAc,MAAM,SAAS,aAAa,KAAK,UAAU,UAAU,MAAM,GAAG;AAC/E;AAAA,IACF;AAEA,SAAK,KAAK,0BAA0B,OAAO,KAAK;AAChD,UAAM,eAAe;AACrB,UAAM,OAAO,KAAK,UAAU,UAAU;AACtC,UAAM,MAAM,IAAI,IAAI,KAAK,MAAM;AAE/B,QAAI,SAAS,IAAI,gBAAgB,IAAI,SAAS,KAAK,GAAG,CAAC,EAAE,SAAS;AAElE,SAAK,KAAK,IAAI,SAAS,CAAC;AAAA,EAC1B;AAAA,EAKA,UAAU,SAAS,IAAI;AACrB,WAAO,IAAI,UAAU,EAAE,gBAAgB,QAAQ,WAAW;AAAA,EAC5D;AAAA,EAKA,MAAM,KAAK,KAAY,SAAuC,MAAM;AAClE,SAAK,KAAK,QAAQ,GAAG;AACrB,UAAM,YAAY,IAAI,IAAI,GAAG;AAE7B,QAAI,UAAU,WAAW,OAAO,SAAS,QAAQ;AAC/C,YAAM,IAAI,MAAM,uCAAuC;AAAA,IACzD;AAEA,SAAK,MAAM,gBAAgB,GAAG;AAG9B,UAAM,UAAU,MAAM,KAAK,MAAM,GAAG;AACpC,UAAM,MAAM,KAAK,UAAU,OAAO;AAClC,UAAM,KAAK,IAAI,cAAc,IAAI,KAAK,IAAI;AAE1C,UAAM,WAAW,IAAI,MAAM,EAAiB;AAC5C,aAAS,UAAU,YAAY;AAE/B,SAAK,MAAM,eAAe,KAAK,OAAO;AAEtC,SAAK,MAAM,cAAc;AAEzB,UAAM,QAAQ,IAAI,KAAK,0BAA0B,IAAI,CAAC,WAAW,OAAO,MAAM,CAAC,CAAC;AAEhF,SAAK,MAAM,aAAa;AACxB,SAAK,MAAM,gBAAgB;AAI3B,SAAK,0BAA0B;AAAA,MAAI,CAAC,QAAQ,UAC1C,OAAO,cAAc,SAAS,0BAA0B,MAAM;AAAA,IAChE;AAGA,QAAI,KAAK,SAAS,SAAS;AACzB,eAAS,QAAQ,IAAI;AACrB,kBAAY,EAAE,MAAM,UAAU,UAAU,QAAQ,UAAU,aAAa,CAAC;AAAA,IAC1E;AAEA,QAAI,QAAQ;AACV,eAAS,iBAAiB,YAAY,OAAO;AAC7C,eAAS,iBAAiB,aAAa,OAAO;AAAA,IAChD;AAGA,UAAM,UAAU;AAChB,SAAK,MAAM,QAAQ;AACnB,UAAM,UAAU;AAEhB,SAAK,MAAM,eAAe;AAC1B,SAAK,MAAM,cAAc;AAGzB,UAAM,QAAQ,IAAI,KAAK,0BAA0B,IAAI,CAAC,WAAW,OAAO,MAAM,CAAC,CAAC;AAEhF,SAAK,MAAM,aAAa;AAAA,EAC1B;AAAA,EAKA,MAAM,MAAM,KAA4B;AACtC,UAAM,SAAS,MAAM,IAAI,GAAG;AAE5B,QAAI,QAAQ;AACV,UAAI,OAAO,WAAW,WAAW;AAC/B,eAAO,OAAO;AAAA,MAChB;AAEA,aAAO,OAAO;AAAA,IAChB;AAEA,UAAM,UAAU,MAAM,GAAG,EAAE,KAAK,CAAC,aAAa,SAAS,KAAK,CAAC;AAE7D,QAAI;AACF,YAAM,IAAI,KAAK;AAAA,QACb;AAAA,QACA,QAAQ;AAAA,QACR,SAAS;AAAA,MACX,CAAC;AAED,YAAM,UAAU,MAAM;AAEtB,YAAM,IAAI,KAAK;AAAA,QACb;AAAA,QACA,QAAQ;AAAA,QACR;AAAA,MACF,CAAC;AAED,aAAO;AAAA,IACT,SAAS,KAAP;AACA,YAAM,IAAI,KAAK;AAAA,QACb;AAAA,QACA,QAAQ;AAAA,QACR,SAAS;AAAA,MACX,CAAC;AAED,aAAO;AAAA,IACT;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["import { Base, isDirectChild, getDirectChildren } from '@studiometa/js-toolkit';\nimport type { BaseProps, BaseConfig } from '@studiometa/js-toolkit';\nimport { nextFrame, historyPush } from '@studiometa/js-toolkit/utils';\nimport { FrameAnchor } from './FrameAnchor.js';\nimport { FrameForm } from './FrameForm.js';\nimport { FrameTarget } from './FrameTarget.js';\n\n/**\n * Get the scroll position.\n */\nfunction getScrollPosition() {\n return {\n left: window.pageXOffset,\n top: window.pageYOffset,\n };\n}\n\n/**\n * The fetch cache.\n */\nconst cache: Map<\n string,\n { promise: Promise<string>; status: 'pending' | 'resolved' | 'error'; content: string }\n> = new Map();\n\nexport interface FrameProps extends BaseProps {\n $children: {\n FrameAnchor: FrameAnchor[];\n FrameForm: FrameForm[];\n FrameTarget: FrameTarget[];\n // eslint-disable-next-line no-use-before-define\n Frame: Frame[];\n };\n $options: {\n history: boolean;\n };\n}\n\n/**\n * Class.\n */\nexport class Frame<T extends BaseProps = BaseProps> extends Base<T & FrameProps> {\n /**\n * Config.\n */\n static config: BaseConfig = {\n name: 'Frame',\n emits: [\n 'before-fetch',\n 'after-fetch',\n 'before-leave',\n 'after-leave',\n 'before-content',\n 'after-content',\n 'before-enter',\n 'after-enter',\n ],\n components: {\n FrameAnchor,\n FrameForm,\n FrameTarget,\n Frame,\n },\n options: {\n history: Boolean,\n },\n };\n\n /**\n * Get uniq id.\n */\n get id() {\n return this.$el.id;\n }\n\n /**\n * Get direct `FrameTarget` children.\n */\n get directChildrenFrameTarget(): FrameTarget[] {\n return getDirectChildren(this, 'Frame', 'FrameTarget');\n }\n\n /**\n * Prevent scroll top on unload.\n */\n onWindowUnload() {\n const { history } = window;\n\n if (!history.state) {\n return;\n }\n\n history.replaceState(\n {\n ...history.state,\n scroll: getScrollPosition(),\n },\n '',\n );\n }\n\n /**\n * Go to the previous URL on `popstate` event.\n */\n onWindowPopstate(event: PopStateEvent) {\n this.goTo(window.location.href, event.state);\n }\n\n /**\n * Prevent click on `FrameAnchor`.\n */\n onFrameAnchorClick(index: number, event: MouseEvent) {\n // Prevent propagation of nested frames\n if (!isDirectChild(this, 'Frame', 'FrameAnchor', this.$children.FrameAnchor[index])) {\n return;\n }\n\n this.$log('onAFrameClick', index, event);\n event.preventDefault();\n const anchor = this.$children.FrameAnchor[index];\n\n // Do nothing when clicking links on the same page\n // @todo handle hash change\n if (anchor.href === window.location.href) {\n return;\n }\n\n this.goTo(anchor.href);\n }\n\n /**\n * Prevent submit on forms.\n */\n onFrameFormSubmit(index: number, event: SubmitEvent) {\n // Prevent propagation of nested frames\n if (!isDirectChild(this, 'Frame', 'FrameForm', this.$children.FrameForm[index])) {\n return;\n }\n\n this.$log('onFrameFormFrameSubmit', index, event);\n event.preventDefault();\n const form = this.$children.FrameForm[index];\n const url = new URL(form.action);\n // @ts-ignore\n url.search = new URLSearchParams(new FormData(form.$el)).toString();\n // @todo handle post request\n this.goTo(url.toString());\n }\n\n /**\n * Parge an HTML string into a DOM object.\n */\n parseHTML(string = '') {\n return new DOMParser().parseFromString(string, 'text/html');\n }\n\n /**\n * Go to the given url.\n */\n async goTo(url: string, scroll: { top: number; left: number } = null) {\n this.$log('goTo', url);\n const parsedUrl = new URL(url);\n\n if (parsedUrl.origin !== window.location.origin) {\n throw new Error('Cross origin request are not allowed.');\n }\n\n this.$emit('before-fetch', url);\n\n // @todo add option to use content as is or to parse it and extract the new frame\n const content = await this.fetch(url);\n const doc = this.parseHTML(content);\n const el = doc.querySelector(`#${this.id}`);\n // @todo manage el === null\n const newFrame = new Frame(el as HTMLElement);\n newFrame.$children.registerAll();\n\n this.$emit('after-fetch', url, content);\n\n this.$emit('before-leave');\n // Leave all\n await Promise.all(this.directChildrenFrameTarget.map((target) => target.leave()));\n\n this.$emit('after-leave');\n this.$emit('before-content');\n\n // Update content\n // @todo insert non existing FrameTarget as well\n this.directChildrenFrameTarget.map((target, index) =>\n target.updateContent(newFrame.directChildrenFrameTarget[index]),\n );\n\n // Push history\n if (this.$options.history) {\n document.title = doc.title;\n historyPush({ path: parsedUrl.pathname, search: parsedUrl.searchParams });\n }\n\n if (scroll) {\n document.scrollingElement.scrollTop = scroll.top;\n document.scrollingElement.scrollLeft = scroll.left;\n }\n\n // Update components\n await nextFrame();\n this.$root.$update();\n await nextFrame();\n\n this.$emit('after-content');\n this.$emit('before-enter');\n\n // Enter all\n await Promise.all(this.directChildrenFrameTarget.map((target) => target.enter()));\n\n this.$emit('after-enter');\n }\n\n /**\n * Fetch the given url.\n */\n async fetch(url: string): Promise<string> {\n const cached = cache.get(url);\n\n if (cached) {\n if (cached.status === 'pending') {\n return cached.promise;\n }\n\n return cached.content;\n }\n\n const promise = fetch(url).then((response) => response.text());\n\n try {\n cache.set(url, {\n promise,\n status: 'pending',\n content: undefined,\n });\n\n const content = await promise;\n\n cache.set(url, {\n promise,\n status: 'resolved',\n content,\n });\n\n return content;\n } catch (err) {\n cache.set(url, {\n promise,\n status: 'error',\n content: err,\n });\n\n return err;\n }\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -29,10 +29,16 @@ __export(FrameAnchor_exports, {
29
29
  module.exports = __toCommonJS(FrameAnchor_exports);
30
30
  var import_js_toolkit = require("@studiometa/js-toolkit");
31
31
  var FrameAnchor = class extends import_js_toolkit.Base {
32
+ /**
33
+ * Get the URL.
34
+ */
32
35
  get href() {
33
36
  return this.$el.href;
34
37
  }
35
38
  };
39
+ /**
40
+ * Config.
41
+ */
36
42
  __publicField(FrameAnchor, "config", {
37
43
  name: "FrameAnchor"
38
44
  });
@@ -2,6 +2,6 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../packages/ui/organisms/Frame/FrameAnchor.ts"],
4
4
  "sourcesContent": ["import { Base } from '@studiometa/js-toolkit';\nimport type { BaseConfig, BaseProps } from '@studiometa/js-toolkit';\n\nexport interface FrameAnchorProps extends BaseProps {\n $el: HTMLAnchorElement;\n}\n\n/**\n * FrameAnchor class.\n */\nexport class FrameAnchor<T extends BaseProps = BaseProps> extends Base<T & FrameAnchorProps> {\n /**\n * Config.\n */\n static config: BaseConfig = {\n name: 'FrameAnchor',\n };\n\n /**\n * Get the URL.\n */\n get href(): string {\n return this.$el.href;\n }\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAAqB;AAUd,IAAM,cAAN,cAA2D,uBAA2B;AAAA,EAW3F,IAAI,OAAe;AACjB,WAAO,KAAK,IAAI;AAAA,EAClB;AACF;AAVE,cAJW,aAIJ,UAAqB;AAAA,EAC1B,MAAM;AACR;",
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAAqB;AAUd,IAAM,cAAN,cAA2D,uBAA2B;AAAA;AAAA;AAAA;AAAA,EAW3F,IAAI,OAAe;AACjB,WAAO,KAAK,IAAI;AAAA,EAClB;AACF;AAAA;AAAA;AAAA;AAVE,cAJW,aAIJ,UAAqB;AAAA,EAC1B,MAAM;AACR;",
6
6
  "names": []
7
7
  }
@@ -1,8 +1,14 @@
1
1
  import { Base } from "@studiometa/js-toolkit";
2
2
  class FrameAnchor extends Base {
3
+ /**
4
+ * Config.
5
+ */
3
6
  static config = {
4
7
  name: "FrameAnchor"
5
8
  };
9
+ /**
10
+ * Get the URL.
11
+ */
6
12
  get href() {
7
13
  return this.$el.href;
8
14
  }
@@ -2,6 +2,6 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../packages/ui/organisms/Frame/FrameAnchor.ts"],
4
4
  "sourcesContent": ["import { Base } from '@studiometa/js-toolkit';\nimport type { BaseConfig, BaseProps } from '@studiometa/js-toolkit';\n\nexport interface FrameAnchorProps extends BaseProps {\n $el: HTMLAnchorElement;\n}\n\n/**\n * FrameAnchor class.\n */\nexport class FrameAnchor<T extends BaseProps = BaseProps> extends Base<T & FrameAnchorProps> {\n /**\n * Config.\n */\n static config: BaseConfig = {\n name: 'FrameAnchor',\n };\n\n /**\n * Get the URL.\n */\n get href(): string {\n return this.$el.href;\n }\n}\n"],
5
- "mappings": "AAAA,SAAS,YAAY;AAUd,MAAM,oBAAqD,KAA2B;AAAA,EAI3F,OAAO,SAAqB;AAAA,IAC1B,MAAM;AAAA,EACR;AAAA,EAKA,IAAI,OAAe;AACjB,WAAO,KAAK,IAAI;AAAA,EAClB;AACF;",
5
+ "mappings": "AAAA,SAAS,YAAY;AAUd,MAAM,oBAAqD,KAA2B;AAAA;AAAA;AAAA;AAAA,EAI3F,OAAO,SAAqB;AAAA,IAC1B,MAAM;AAAA,EACR;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,OAAe;AACjB,WAAO,KAAK,IAAI;AAAA,EAClB;AACF;",
6
6
  "names": []
7
7
  }
@@ -29,10 +29,16 @@ __export(FrameForm_exports, {
29
29
  module.exports = __toCommonJS(FrameForm_exports);
30
30
  var import_js_toolkit = require("@studiometa/js-toolkit");
31
31
  var FrameForm = class extends import_js_toolkit.Base {
32
+ /**
33
+ * Get the form action.
34
+ */
32
35
  get action() {
33
36
  return this.$el.action;
34
37
  }
35
38
  };
39
+ /**
40
+ * Config.
41
+ */
36
42
  __publicField(FrameForm, "config", {
37
43
  name: "FrameForm"
38
44
  });
@@ -2,6 +2,6 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../packages/ui/organisms/Frame/FrameForm.ts"],
4
4
  "sourcesContent": ["import { Base } from '@studiometa/js-toolkit';\nimport type { BaseProps, BaseConfig } from '@studiometa/js-toolkit';\n\nexport interface FrameFormProps extends BaseProps {\n $el: HTMLFormElement;\n}\n\n/**\n * FrameForm class.\n */\nexport class FrameForm<T extends BaseProps = BaseProps> extends Base<T & FrameFormProps> {\n /**\n * Config.\n */\n static config: BaseConfig = {\n name: 'FrameForm',\n };\n\n /**\n * Get the form action.\n */\n get action(): string {\n return this.$el.action;\n }\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAAqB;AAUd,IAAM,YAAN,cAAyD,uBAAyB;AAAA,EAWvF,IAAI,SAAiB;AACnB,WAAO,KAAK,IAAI;AAAA,EAClB;AACF;AAVE,cAJW,WAIJ,UAAqB;AAAA,EAC1B,MAAM;AACR;",
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAAqB;AAUd,IAAM,YAAN,cAAyD,uBAAyB;AAAA;AAAA;AAAA;AAAA,EAWvF,IAAI,SAAiB;AACnB,WAAO,KAAK,IAAI;AAAA,EAClB;AACF;AAAA;AAAA;AAAA;AAVE,cAJW,WAIJ,UAAqB;AAAA,EAC1B,MAAM;AACR;",
6
6
  "names": []
7
7
  }
@@ -1,8 +1,14 @@
1
1
  import { Base } from "@studiometa/js-toolkit";
2
2
  class FrameForm extends Base {
3
+ /**
4
+ * Config.
5
+ */
3
6
  static config = {
4
7
  name: "FrameForm"
5
8
  };
9
+ /**
10
+ * Get the form action.
11
+ */
6
12
  get action() {
7
13
  return this.$el.action;
8
14
  }
@@ -2,6 +2,6 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../packages/ui/organisms/Frame/FrameForm.ts"],
4
4
  "sourcesContent": ["import { Base } from '@studiometa/js-toolkit';\nimport type { BaseProps, BaseConfig } from '@studiometa/js-toolkit';\n\nexport interface FrameFormProps extends BaseProps {\n $el: HTMLFormElement;\n}\n\n/**\n * FrameForm class.\n */\nexport class FrameForm<T extends BaseProps = BaseProps> extends Base<T & FrameFormProps> {\n /**\n * Config.\n */\n static config: BaseConfig = {\n name: 'FrameForm',\n };\n\n /**\n * Get the form action.\n */\n get action(): string {\n return this.$el.action;\n }\n}\n"],
5
- "mappings": "AAAA,SAAS,YAAY;AAUd,MAAM,kBAAmD,KAAyB;AAAA,EAIvF,OAAO,SAAqB;AAAA,IAC1B,MAAM;AAAA,EACR;AAAA,EAKA,IAAI,SAAiB;AACnB,WAAO,KAAK,IAAI;AAAA,EAClB;AACF;",
5
+ "mappings": "AAAA,SAAS,YAAY;AAUd,MAAM,kBAAmD,KAAyB;AAAA;AAAA;AAAA;AAAA,EAIvF,OAAO,SAAqB;AAAA,IAC1B,MAAM;AAAA,EACR;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,SAAiB;AACnB,WAAO,KAAK,IAAI;AAAA,EAClB;AACF;",
6
6
  "names": []
7
7
  }
@@ -30,14 +30,24 @@ module.exports = __toCommonJS(FrameTarget_exports);
30
30
  var import_utils = require("@studiometa/js-toolkit/utils");
31
31
  var import_primitives = require("../../primitives/index.cjs");
32
32
  var _FrameTarget = class extends import_primitives.Transition {
33
+ /**
34
+ * Override options.
35
+ */
36
+ // @ts-ignore
33
37
  get $options() {
34
38
  const options = super.$options;
35
39
  options.leaveKeep = true;
36
40
  return options;
37
41
  }
42
+ /**
43
+ * Get uniq ID.
44
+ */
38
45
  get id() {
39
46
  return this.$options.id ?? this.$el.id;
40
47
  }
48
+ /**
49
+ * Enter transition.
50
+ */
41
51
  async enter() {
42
52
  this.$log("enter");
43
53
  const { enterFrom: from, enterActive: active, enterTo: to, leaveTo, enterKeep } = this.$options;
@@ -49,16 +59,22 @@ var _FrameTarget = class extends import_primitives.Transition {
49
59
  Array.from(this.$el.children).filter(
50
60
  (child) => from.split(" ").every((className) => child.classList.contains(className))
51
61
  ).map(
52
- (child) => (0, import_utils.transition)(child, transitionStyles, enterKeep && "keep")
62
+ (child) => (0, import_utils.transition)(child, transitionStyles, enterKeep ? "keep" : void 0)
53
63
  )
54
64
  );
55
65
  break;
56
66
  case "replace":
57
67
  default:
58
68
  transitionStyles.from = Array.from(new Set([from, leaveTo].flat())).join(" ");
59
- await (0, import_utils.transition)(this.$el, transitionStyles, enterKeep && "keep");
69
+ await (0, import_utils.transition)(this.$el, transitionStyles, enterKeep ? "keep" : void 0);
60
70
  }
61
71
  }
72
+ /**
73
+ * Update the content from the new target.
74
+ *
75
+ * @param {FrameTarget} newTarget The instance of the new target.
76
+ * @returns {void}
77
+ */
62
78
  updateContent(newTarget) {
63
79
  switch (this.$options.mode) {
64
80
  case "prepend":
@@ -77,6 +93,9 @@ var _FrameTarget = class extends import_primitives.Transition {
77
93
  }
78
94
  };
79
95
  var FrameTarget = _FrameTarget;
96
+ /**
97
+ * Config.
98
+ */
80
99
  __publicField(FrameTarget, "config", {
81
100
  ...import_primitives.Transition.config,
82
101
  name: "FrameTarget",
@@ -86,10 +105,14 @@ __publicField(FrameTarget, "config", {
86
105
  mode: {
87
106
  type: String,
88
107
  default: "replace"
108
+ // or 'prepend' or 'append'
89
109
  },
90
110
  id: String
91
111
  }
92
112
  });
113
+ /**
114
+ * Insert modes.
115
+ */
93
116
  __publicField(FrameTarget, "__INSERT_MODES", {
94
117
  prepend: "afterbegin",
95
118
  append: "beforeend"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../packages/ui/organisms/Frame/FrameTarget.ts"],
4
- "sourcesContent": ["import type { BaseConfig, BaseProps } from '@studiometa/js-toolkit';\nimport { addClass, transition } from '@studiometa/js-toolkit/utils';\nimport { Transition } from '../../primitives/index.js';\n\nexport interface FrameTargetProps extends BaseProps {\n $options: {\n mode: 'replace' | 'prepend' | 'append';\n id: string;\n leaveKeep: true;\n };\n}\n\n/**\n * FrameTarget class.\n */\nexport class FrameTarget<T extends BaseProps = BaseProps> extends Transition<T & FrameTargetProps> {\n /**\n * Config.\n */\n static config: BaseConfig = {\n ...Transition.config,\n name: 'FrameTarget',\n log: true,\n options: {\n ...Transition.config.options,\n mode: {\n type: String,\n default: 'replace', // or 'prepend' or 'append'\n },\n id: String,\n },\n };\n\n /**\n * Insert modes.\n */\n static __INSERT_MODES = {\n prepend: 'afterbegin',\n append: 'beforeend',\n } as const;\n\n /**\n * Override options.\n */\n // @ts-ignore\n get $options() {\n const options = super.$options;\n\n options.leaveKeep = true;\n\n return options;\n }\n\n /**\n * Get uniq ID.\n */\n get id(): string {\n return this.$options.id ?? this.$el.id;\n }\n\n /**\n * Enter transition.\n */\n async enter() {\n this.$log('enter');\n\n const { enterFrom: from, enterActive: active, enterTo: to, leaveTo, enterKeep } = this.$options;\n const transitionStyles = { from, active, to };\n\n switch (this.$options.mode) {\n case 'append':\n case 'prepend':\n await Promise.all(\n Array.from(this.$el.children)\n .filter((child) =>\n from.split(' ').every((className) => child.classList.contains(className)),\n )\n .map((child) =>\n transition(child as HTMLElement, transitionStyles, enterKeep && 'keep'),\n ),\n );\n break;\n case 'replace':\n default:\n transitionStyles.from = Array.from(new Set([from, leaveTo].flat())).join(' ');\n await transition(this.$el, transitionStyles, enterKeep && 'keep');\n }\n }\n\n /**\n * Update the content from the new target.\n *\n * @param {FrameTarget} newTarget The instance of the new target.\n * @returns {void}\n */\n updateContent(newTarget:FrameTarget) {\n // @todo manage 'prepend' and 'append' transition\n // only the new content should have the transition\n // - add the leaveTo and enterFrom classes to all `newTarget.children`\n // - or wrap the new content in a custom div ?\n switch (this.$options.mode) {\n case 'prepend':\n case 'append':\n addClass(Array.from(newTarget.$el.children), this.$options.enterFrom.split(' '));\n this.$el.insertAdjacentHTML(\n FrameTarget.__INSERT_MODES[this.$options.mode],\n newTarget.$el.innerHTML,\n );\n break;\n case 'replace':\n default:\n this.$el.innerHTML = newTarget.$el.innerHTML;\n break;\n }\n }\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,mBAAqC;AACrC,wBAA2B;AAapB,IAAM,eAAN,cAA2D,6BAAiC;AAAA,EA8BjG,IAAI,WAAW;AACb,UAAM,UAAU,MAAM;AAEtB,YAAQ,YAAY;AAEpB,WAAO;AAAA,EACT;AAAA,EAKA,IAAI,KAAa;AACf,WAAO,KAAK,SAAS,MAAM,KAAK,IAAI;AAAA,EACtC;AAAA,EAKA,MAAM,QAAQ;AACZ,SAAK,KAAK,OAAO;AAEjB,UAAM,EAAE,WAAW,MAAM,aAAa,QAAQ,SAAS,IAAI,SAAS,UAAU,IAAI,KAAK;AACvF,UAAM,mBAAmB,EAAE,MAAM,QAAQ,GAAG;AAE5C,YAAQ,KAAK,SAAS,MAAM;AAAA,MAC1B,KAAK;AAAA,MACL,KAAK;AACH,cAAM,QAAQ;AAAA,UACZ,MAAM,KAAK,KAAK,IAAI,QAAQ,EACzB;AAAA,YAAO,CAAC,UACP,KAAK,MAAM,GAAG,EAAE,MAAM,CAAC,cAAc,MAAM,UAAU,SAAS,SAAS,CAAC;AAAA,UAC1E,EACC;AAAA,YAAI,CAAC,cACJ,yBAAW,OAAsB,kBAAkB,aAAa,MAAM;AAAA,UACxE;AAAA,QACJ;AACA;AAAA,MACF,KAAK;AAAA,MACL;AACE,yBAAiB,OAAO,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,OAAO,EAAE,KAAK,CAAC,CAAC,EAAE,KAAK,GAAG;AAC5E,kBAAM,yBAAW,KAAK,KAAK,kBAAkB,aAAa,MAAM;AAAA,IACpE;AAAA,EACF;AAAA,EAQA,cAAc,WAAuB;AAKnC,YAAQ,KAAK,SAAS,MAAM;AAAA,MAC1B,KAAK;AAAA,MACL,KAAK;AACH,mCAAS,MAAM,KAAK,UAAU,IAAI,QAAQ,GAAG,KAAK,SAAS,UAAU,MAAM,GAAG,CAAC;AAC/E,aAAK,IAAI;AAAA,UACP,aAAY,eAAe,KAAK,SAAS;AAAA,UACzC,UAAU,IAAI;AAAA,QAChB;AACA;AAAA,MACF,KAAK;AAAA,MACL;AACE,aAAK,IAAI,YAAY,UAAU,IAAI;AACnC;AAAA,IACJ;AAAA,EACF;AACF;AApGO,IAAM,cAAN;AAIL,cAJW,aAIJ,UAAqB;AAAA,EAC1B,GAAG,6BAAW;AAAA,EACd,MAAM;AAAA,EACN,KAAK;AAAA,EACL,SAAS;AAAA,IACP,GAAG,6BAAW,OAAO;AAAA,IACrB,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,IACA,IAAI;AAAA,EACN;AACF;AAKA,cArBW,aAqBJ,kBAAiB;AAAA,EACtB,SAAS;AAAA,EACT,QAAQ;AACV;",
4
+ "sourcesContent": ["import type { BaseConfig, BaseProps } from '@studiometa/js-toolkit';\nimport { addClass, transition } from '@studiometa/js-toolkit/utils';\nimport { Transition } from '../../primitives/index.js';\n\nexport interface FrameTargetProps extends BaseProps {\n $options: {\n mode: 'replace' | 'prepend' | 'append';\n id: string;\n leaveKeep: true;\n };\n}\n\n/**\n * FrameTarget class.\n */\nexport class FrameTarget<T extends BaseProps = BaseProps> extends Transition<T & FrameTargetProps> {\n /**\n * Config.\n */\n static config: BaseConfig = {\n ...Transition.config,\n name: 'FrameTarget',\n log: true,\n options: {\n ...Transition.config.options,\n mode: {\n type: String,\n default: 'replace', // or 'prepend' or 'append'\n },\n id: String,\n },\n };\n\n /**\n * Insert modes.\n */\n static __INSERT_MODES = {\n prepend: 'afterbegin',\n append: 'beforeend',\n } as const;\n\n /**\n * Override options.\n */\n // @ts-ignore\n get $options() {\n const options = super.$options;\n\n options.leaveKeep = true;\n\n return options;\n }\n\n /**\n * Get uniq ID.\n */\n get id(): string {\n return this.$options.id ?? this.$el.id;\n }\n\n /**\n * Enter transition.\n */\n async enter() {\n this.$log('enter');\n\n const { enterFrom: from, enterActive: active, enterTo: to, leaveTo, enterKeep } = this.$options;\n const transitionStyles = { from, active, to };\n\n switch (this.$options.mode) {\n case 'append':\n case 'prepend':\n await Promise.all(\n Array.from(this.$el.children)\n .filter((child) =>\n from.split(' ').every((className) => child.classList.contains(className)),\n )\n .map((child) =>\n transition(child as HTMLElement, transitionStyles, enterKeep ? 'keep' : undefined),\n ),\n );\n break;\n case 'replace':\n default:\n transitionStyles.from = Array.from(new Set([from, leaveTo].flat())).join(' ');\n await transition(this.$el, transitionStyles, enterKeep ? 'keep' : undefined);\n }\n }\n\n /**\n * Update the content from the new target.\n *\n * @param {FrameTarget} newTarget The instance of the new target.\n * @returns {void}\n */\n updateContent(newTarget: FrameTarget) {\n // @todo manage 'prepend' and 'append' transition\n // only the new content should have the transition\n // - add the leaveTo and enterFrom classes to all `newTarget.children`\n // - or wrap the new content in a custom div ?\n switch (this.$options.mode) {\n case 'prepend':\n case 'append':\n addClass(Array.from(newTarget.$el.children), this.$options.enterFrom.split(' '));\n this.$el.insertAdjacentHTML(\n FrameTarget.__INSERT_MODES[this.$options.mode],\n newTarget.$el.innerHTML,\n );\n break;\n case 'replace':\n default:\n this.$el.innerHTML = newTarget.$el.innerHTML;\n break;\n }\n }\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,mBAAqC;AACrC,wBAA2B;AAapB,IAAM,eAAN,cAA2D,6BAAiC;AAAA;AAAA;AAAA;AAAA;AAAA,EA8BjG,IAAI,WAAW;AACb,UAAM,UAAU,MAAM;AAEtB,YAAQ,YAAY;AAEpB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,KAAa;AACf,WAAO,KAAK,SAAS,MAAM,KAAK,IAAI;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAQ;AACZ,SAAK,KAAK,OAAO;AAEjB,UAAM,EAAE,WAAW,MAAM,aAAa,QAAQ,SAAS,IAAI,SAAS,UAAU,IAAI,KAAK;AACvF,UAAM,mBAAmB,EAAE,MAAM,QAAQ,GAAG;AAE5C,YAAQ,KAAK,SAAS,MAAM;AAAA,MAC1B,KAAK;AAAA,MACL,KAAK;AACH,cAAM,QAAQ;AAAA,UACZ,MAAM,KAAK,KAAK,IAAI,QAAQ,EACzB;AAAA,YAAO,CAAC,UACP,KAAK,MAAM,GAAG,EAAE,MAAM,CAAC,cAAc,MAAM,UAAU,SAAS,SAAS,CAAC;AAAA,UAC1E,EACC;AAAA,YAAI,CAAC,cACJ,yBAAW,OAAsB,kBAAkB,YAAY,SAAS,MAAS;AAAA,UACnF;AAAA,QACJ;AACA;AAAA,MACF,KAAK;AAAA,MACL;AACE,yBAAiB,OAAO,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,OAAO,EAAE,KAAK,CAAC,CAAC,EAAE,KAAK,GAAG;AAC5E,kBAAM,yBAAW,KAAK,KAAK,kBAAkB,YAAY,SAAS,MAAS;AAAA,IAC/E;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,cAAc,WAAwB;AAKpC,YAAQ,KAAK,SAAS,MAAM;AAAA,MAC1B,KAAK;AAAA,MACL,KAAK;AACH,mCAAS,MAAM,KAAK,UAAU,IAAI,QAAQ,GAAG,KAAK,SAAS,UAAU,MAAM,GAAG,CAAC;AAC/E,aAAK,IAAI;AAAA,UACP,aAAY,eAAe,KAAK,SAAS,IAAI;AAAA,UAC7C,UAAU,IAAI;AAAA,QAChB;AACA;AAAA,MACF,KAAK;AAAA,MACL;AACE,aAAK,IAAI,YAAY,UAAU,IAAI;AACnC;AAAA,IACJ;AAAA,EACF;AACF;AApGO,IAAM,cAAN;AAAA;AAAA;AAAA;AAIL,cAJW,aAIJ,UAAqB;AAAA,EAC1B,GAAG,6BAAW;AAAA,EACd,MAAM;AAAA,EACN,KAAK;AAAA,EACL,SAAS;AAAA,IACP,GAAG,6BAAW,OAAO;AAAA,IACrB,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,SAAS;AAAA;AAAA,IACX;AAAA,IACA,IAAI;AAAA,EACN;AACF;AAAA;AAAA;AAAA;AAKA,cArBW,aAqBJ,kBAAiB;AAAA,EACtB,SAAS;AAAA,EACT,QAAQ;AACV;",
6
6
  "names": []
7
7
  }