@dazl/shorthands-opener 4.2.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.
Files changed (237) hide show
  1. package/README.md +3 -0
  2. package/dist/compounds/compound-css-data.d.ts +22 -0
  3. package/dist/compounds/compound-css-data.d.ts.map +1 -0
  4. package/dist/compounds/compound-css-data.js +2 -0
  5. package/dist/compounds/compound-css-data.js.map +1 -0
  6. package/dist/compounds/compound-mapper.d.ts +4 -0
  7. package/dist/compounds/compound-mapper.d.ts.map +1 -0
  8. package/dist/compounds/compound-mapper.js +10 -0
  9. package/dist/compounds/compound-mapper.js.map +1 -0
  10. package/dist/compounds/compound-parser-utils.d.ts +3 -0
  11. package/dist/compounds/compound-parser-utils.d.ts.map +1 -0
  12. package/dist/compounds/compound-parser-utils.js +33 -0
  13. package/dist/compounds/compound-parser-utils.js.map +1 -0
  14. package/dist/compounds/compound-types.d.ts +26 -0
  15. package/dist/compounds/compound-types.d.ts.map +1 -0
  16. package/dist/compounds/compound-types.js +2 -0
  17. package/dist/compounds/compound-types.js.map +1 -0
  18. package/dist/compounds/compound-value-parsers.d.ts +6 -0
  19. package/dist/compounds/compound-value-parsers.d.ts.map +1 -0
  20. package/dist/compounds/compound-value-parsers.js +5 -0
  21. package/dist/compounds/compound-value-parsers.js.map +1 -0
  22. package/dist/compounds/index.d.ts +6 -0
  23. package/dist/compounds/index.d.ts.map +1 -0
  24. package/dist/compounds/index.js +6 -0
  25. package/dist/compounds/index.js.map +1 -0
  26. package/dist/compounds/parsers/index.d.ts +2 -0
  27. package/dist/compounds/parsers/index.d.ts.map +1 -0
  28. package/dist/compounds/parsers/index.js +2 -0
  29. package/dist/compounds/parsers/index.js.map +1 -0
  30. package/dist/compounds/parsers/shadow-compound.d.ts +5 -0
  31. package/dist/compounds/parsers/shadow-compound.d.ts.map +1 -0
  32. package/dist/compounds/parsers/shadow-compound.js +39 -0
  33. package/dist/compounds/parsers/shadow-compound.js.map +1 -0
  34. package/dist/css-data-types/data-types-consts.d.ts +212 -0
  35. package/dist/css-data-types/data-types-consts.d.ts.map +1 -0
  36. package/dist/css-data-types/data-types-consts.js +790 -0
  37. package/dist/css-data-types/data-types-consts.js.map +1 -0
  38. package/dist/css-data-types/data-types-predicates.d.ts +32 -0
  39. package/dist/css-data-types/data-types-predicates.d.ts.map +1 -0
  40. package/dist/css-data-types/data-types-predicates.js +353 -0
  41. package/dist/css-data-types/data-types-predicates.js.map +1 -0
  42. package/dist/css-data-types/data-types-state-machines.d.ts +14 -0
  43. package/dist/css-data-types/data-types-state-machines.d.ts.map +1 -0
  44. package/dist/css-data-types/data-types-state-machines.js +129 -0
  45. package/dist/css-data-types/data-types-state-machines.js.map +1 -0
  46. package/dist/css-data-types/data-types-types.d.ts +26 -0
  47. package/dist/css-data-types/data-types-types.d.ts.map +1 -0
  48. package/dist/css-data-types/data-types-types.js +2 -0
  49. package/dist/css-data-types/data-types-types.js.map +1 -0
  50. package/dist/css-data-types/data-types-utils.d.ts +31 -0
  51. package/dist/css-data-types/data-types-utils.d.ts.map +1 -0
  52. package/dist/css-data-types/data-types-utils.js +176 -0
  53. package/dist/css-data-types/data-types-utils.js.map +1 -0
  54. package/dist/css-data-types/data-types.d.ts +64 -0
  55. package/dist/css-data-types/data-types.d.ts.map +1 -0
  56. package/dist/css-data-types/data-types.js +304 -0
  57. package/dist/css-data-types/data-types.js.map +1 -0
  58. package/dist/css-data-types/index.d.ts +7 -0
  59. package/dist/css-data-types/index.d.ts.map +1 -0
  60. package/dist/css-data-types/index.js +7 -0
  61. package/dist/css-data-types/index.js.map +1 -0
  62. package/dist/index.d.ts +5 -0
  63. package/dist/index.d.ts.map +1 -0
  64. package/dist/index.js +5 -0
  65. package/dist/index.js.map +1 -0
  66. package/dist/shorthands/index.d.ts +8 -0
  67. package/dist/shorthands/index.d.ts.map +1 -0
  68. package/dist/shorthands/index.js +8 -0
  69. package/dist/shorthands/index.js.map +1 -0
  70. package/dist/shorthands/openers/background-position-shorthand.d.ts +5 -0
  71. package/dist/shorthands/openers/background-position-shorthand.d.ts.map +1 -0
  72. package/dist/shorthands/openers/background-position-shorthand.js +173 -0
  73. package/dist/shorthands/openers/background-position-shorthand.js.map +1 -0
  74. package/dist/shorthands/openers/background-shorthand.d.ts +5 -0
  75. package/dist/shorthands/openers/background-shorthand.d.ts.map +1 -0
  76. package/dist/shorthands/openers/background-shorthand.js +88 -0
  77. package/dist/shorthands/openers/background-shorthand.js.map +1 -0
  78. package/dist/shorthands/openers/border-image-shorthand.d.ts +5 -0
  79. package/dist/shorthands/openers/border-image-shorthand.d.ts.map +1 -0
  80. package/dist/shorthands/openers/border-image-shorthand.js +16 -0
  81. package/dist/shorthands/openers/border-image-shorthand.js.map +1 -0
  82. package/dist/shorthands/openers/border-radius-shorthand.d.ts +5 -0
  83. package/dist/shorthands/openers/border-radius-shorthand.d.ts.map +1 -0
  84. package/dist/shorthands/openers/border-radius-shorthand.js +61 -0
  85. package/dist/shorthands/openers/border-radius-shorthand.js.map +1 -0
  86. package/dist/shorthands/openers/border-shorthand.d.ts +20 -0
  87. package/dist/shorthands/openers/border-shorthand.d.ts.map +1 -0
  88. package/dist/shorthands/openers/border-shorthand.js +90 -0
  89. package/dist/shorthands/openers/border-shorthand.js.map +1 -0
  90. package/dist/shorthands/openers/flex-flow-shorthand.d.ts +5 -0
  91. package/dist/shorthands/openers/flex-flow-shorthand.d.ts.map +1 -0
  92. package/dist/shorthands/openers/flex-flow-shorthand.js +13 -0
  93. package/dist/shorthands/openers/flex-flow-shorthand.js.map +1 -0
  94. package/dist/shorthands/openers/flex-shorthand.d.ts +5 -0
  95. package/dist/shorthands/openers/flex-shorthand.d.ts.map +1 -0
  96. package/dist/shorthands/openers/flex-shorthand.js +55 -0
  97. package/dist/shorthands/openers/flex-shorthand.js.map +1 -0
  98. package/dist/shorthands/openers/font-shorthand.d.ts +5 -0
  99. package/dist/shorthands/openers/font-shorthand.d.ts.map +1 -0
  100. package/dist/shorthands/openers/font-shorthand.js +60 -0
  101. package/dist/shorthands/openers/font-shorthand.js.map +1 -0
  102. package/dist/shorthands/openers/gap-shorthand.d.ts +5 -0
  103. package/dist/shorthands/openers/gap-shorthand.d.ts.map +1 -0
  104. package/dist/shorthands/openers/gap-shorthand.js +28 -0
  105. package/dist/shorthands/openers/gap-shorthand.js.map +1 -0
  106. package/dist/shorthands/openers/grid-axis-shorthand.d.ts +6 -0
  107. package/dist/shorthands/openers/grid-axis-shorthand.d.ts.map +1 -0
  108. package/dist/shorthands/openers/grid-axis-shorthand.js +36 -0
  109. package/dist/shorthands/openers/grid-axis-shorthand.js.map +1 -0
  110. package/dist/shorthands/openers/grid-gap-shorthand.d.ts +5 -0
  111. package/dist/shorthands/openers/grid-gap-shorthand.d.ts.map +1 -0
  112. package/dist/shorthands/openers/grid-gap-shorthand.js +21 -0
  113. package/dist/shorthands/openers/grid-gap-shorthand.js.map +1 -0
  114. package/dist/shorthands/openers/grid-shorthand.d.ts +8 -0
  115. package/dist/shorthands/openers/grid-shorthand.d.ts.map +1 -0
  116. package/dist/shorthands/openers/grid-shorthand.js +145 -0
  117. package/dist/shorthands/openers/grid-shorthand.js.map +1 -0
  118. package/dist/shorthands/openers/grid-template-shorthand.d.ts +10 -0
  119. package/dist/shorthands/openers/grid-template-shorthand.d.ts.map +1 -0
  120. package/dist/shorthands/openers/grid-template-shorthand.js +113 -0
  121. package/dist/shorthands/openers/grid-template-shorthand.js.map +1 -0
  122. package/dist/shorthands/openers/index.d.ts +22 -0
  123. package/dist/shorthands/openers/index.d.ts.map +1 -0
  124. package/dist/shorthands/openers/index.js +22 -0
  125. package/dist/shorthands/openers/index.js.map +1 -0
  126. package/dist/shorthands/openers/list-style-shorthand.d.ts +5 -0
  127. package/dist/shorthands/openers/list-style-shorthand.d.ts.map +1 -0
  128. package/dist/shorthands/openers/list-style-shorthand.js +15 -0
  129. package/dist/shorthands/openers/list-style-shorthand.js.map +1 -0
  130. package/dist/shorthands/openers/margin-shorthand.d.ts +5 -0
  131. package/dist/shorthands/openers/margin-shorthand.d.ts.map +1 -0
  132. package/dist/shorthands/openers/margin-shorthand.js +11 -0
  133. package/dist/shorthands/openers/margin-shorthand.js.map +1 -0
  134. package/dist/shorthands/openers/outline-shorthand.d.ts +5 -0
  135. package/dist/shorthands/openers/outline-shorthand.d.ts.map +1 -0
  136. package/dist/shorthands/openers/outline-shorthand.js +14 -0
  137. package/dist/shorthands/openers/outline-shorthand.js.map +1 -0
  138. package/dist/shorthands/openers/overflow-shorthand.d.ts +5 -0
  139. package/dist/shorthands/openers/overflow-shorthand.d.ts.map +1 -0
  140. package/dist/shorthands/openers/overflow-shorthand.js +21 -0
  141. package/dist/shorthands/openers/overflow-shorthand.js.map +1 -0
  142. package/dist/shorthands/openers/padding-shorthand.d.ts +5 -0
  143. package/dist/shorthands/openers/padding-shorthand.d.ts.map +1 -0
  144. package/dist/shorthands/openers/padding-shorthand.js +11 -0
  145. package/dist/shorthands/openers/padding-shorthand.js.map +1 -0
  146. package/dist/shorthands/openers/place-content-shorthand.d.ts +5 -0
  147. package/dist/shorthands/openers/place-content-shorthand.d.ts.map +1 -0
  148. package/dist/shorthands/openers/place-content-shorthand.js +29 -0
  149. package/dist/shorthands/openers/place-content-shorthand.js.map +1 -0
  150. package/dist/shorthands/openers/place-items-shorthand.d.ts +5 -0
  151. package/dist/shorthands/openers/place-items-shorthand.d.ts.map +1 -0
  152. package/dist/shorthands/openers/place-items-shorthand.js +23 -0
  153. package/dist/shorthands/openers/place-items-shorthand.js.map +1 -0
  154. package/dist/shorthands/openers/text-decoration-shorthand.d.ts +5 -0
  155. package/dist/shorthands/openers/text-decoration-shorthand.d.ts.map +1 -0
  156. package/dist/shorthands/openers/text-decoration-shorthand.js +14 -0
  157. package/dist/shorthands/openers/text-decoration-shorthand.js.map +1 -0
  158. package/dist/shorthands/shorthand-css-data.d.ts +120 -0
  159. package/dist/shorthands/shorthand-css-data.d.ts.map +1 -0
  160. package/dist/shorthands/shorthand-css-data.js +48 -0
  161. package/dist/shorthands/shorthand-css-data.js.map +1 -0
  162. package/dist/shorthands/shorthand-mapper.d.ts +6 -0
  163. package/dist/shorthands/shorthand-mapper.d.ts.map +1 -0
  164. package/dist/shorthands/shorthand-mapper.js +72 -0
  165. package/dist/shorthands/shorthand-mapper.js.map +1 -0
  166. package/dist/shorthands/shorthand-parser-errors.d.ts +25 -0
  167. package/dist/shorthands/shorthand-parser-errors.d.ts.map +1 -0
  168. package/dist/shorthands/shorthand-parser-errors.js +41 -0
  169. package/dist/shorthands/shorthand-parser-errors.js.map +1 -0
  170. package/dist/shorthands/shorthand-parser-utils.d.ts +24 -0
  171. package/dist/shorthands/shorthand-parser-utils.d.ts.map +1 -0
  172. package/dist/shorthands/shorthand-parser-utils.js +398 -0
  173. package/dist/shorthands/shorthand-parser-utils.js.map +1 -0
  174. package/dist/shorthands/shorthand-types.d.ts +64 -0
  175. package/dist/shorthands/shorthand-types.d.ts.map +1 -0
  176. package/dist/shorthands/shorthand-types.js +2 -0
  177. package/dist/shorthands/shorthand-types.js.map +1 -0
  178. package/dist/shorthands/shorthands-ast-evaluation.d.ts +5 -0
  179. package/dist/shorthands/shorthands-ast-evaluation.d.ts.map +1 -0
  180. package/dist/shorthands/shorthands-ast-evaluation.js +19 -0
  181. package/dist/shorthands/shorthands-ast-evaluation.js.map +1 -0
  182. package/dist/tokenizers/css-value-tokenizer.d.ts +43 -0
  183. package/dist/tokenizers/css-value-tokenizer.d.ts.map +1 -0
  184. package/dist/tokenizers/css-value-tokenizer.js +154 -0
  185. package/dist/tokenizers/css-value-tokenizer.js.map +1 -0
  186. package/dist/tokenizers/index.d.ts +2 -0
  187. package/dist/tokenizers/index.d.ts.map +1 -0
  188. package/dist/tokenizers/index.js +2 -0
  189. package/dist/tokenizers/index.js.map +1 -0
  190. package/package.json +54 -0
  191. package/src/compounds/compound-css-data.ts +24 -0
  192. package/src/compounds/compound-mapper.ts +21 -0
  193. package/src/compounds/compound-parser-utils.ts +47 -0
  194. package/src/compounds/compound-types.ts +35 -0
  195. package/src/compounds/compound-value-parsers.ts +12 -0
  196. package/src/compounds/index.ts +5 -0
  197. package/src/compounds/parsers/index.ts +1 -0
  198. package/src/compounds/parsers/shadow-compound.ts +56 -0
  199. package/src/css-data-types/data-types-consts.ts +877 -0
  200. package/src/css-data-types/data-types-predicates.ts +477 -0
  201. package/src/css-data-types/data-types-state-machines.ts +169 -0
  202. package/src/css-data-types/data-types-types.ts +43 -0
  203. package/src/css-data-types/data-types-utils.ts +258 -0
  204. package/src/css-data-types/data-types.ts +435 -0
  205. package/src/css-data-types/index.ts +6 -0
  206. package/src/index.ts +4 -0
  207. package/src/shorthands/index.ts +7 -0
  208. package/src/shorthands/openers/background-position-shorthand.ts +180 -0
  209. package/src/shorthands/openers/background-shorthand.ts +161 -0
  210. package/src/shorthands/openers/border-image-shorthand.ts +35 -0
  211. package/src/shorthands/openers/border-radius-shorthand.ts +93 -0
  212. package/src/shorthands/openers/border-shorthand.ts +198 -0
  213. package/src/shorthands/openers/flex-flow-shorthand.ts +24 -0
  214. package/src/shorthands/openers/flex-shorthand.ts +79 -0
  215. package/src/shorthands/openers/font-shorthand.ts +85 -0
  216. package/src/shorthands/openers/gap-shorthand.ts +47 -0
  217. package/src/shorthands/openers/grid-axis-shorthand.ts +61 -0
  218. package/src/shorthands/openers/grid-gap-shorthand.ts +40 -0
  219. package/src/shorthands/openers/grid-shorthand.ts +260 -0
  220. package/src/shorthands/openers/grid-template-shorthand.ts +176 -0
  221. package/src/shorthands/openers/index.ts +21 -0
  222. package/src/shorthands/openers/list-style-shorthand.ts +33 -0
  223. package/src/shorthands/openers/margin-shorthand.ts +20 -0
  224. package/src/shorthands/openers/outline-shorthand.ts +27 -0
  225. package/src/shorthands/openers/overflow-shorthand.ts +40 -0
  226. package/src/shorthands/openers/padding-shorthand.ts +21 -0
  227. package/src/shorthands/openers/place-content-shorthand.ts +49 -0
  228. package/src/shorthands/openers/place-items-shorthand.ts +43 -0
  229. package/src/shorthands/openers/text-decoration-shorthand.ts +27 -0
  230. package/src/shorthands/shorthand-css-data.ts +210 -0
  231. package/src/shorthands/shorthand-mapper.ts +157 -0
  232. package/src/shorthands/shorthand-parser-errors.ts +47 -0
  233. package/src/shorthands/shorthand-parser-utils.ts +602 -0
  234. package/src/shorthands/shorthand-types.ts +107 -0
  235. package/src/shorthands/shorthands-ast-evaluation.ts +38 -0
  236. package/src/tokenizers/css-value-tokenizer.ts +220 -0
  237. package/src/tokenizers/index.ts +1 -0
@@ -0,0 +1,24 @@
1
+ import type { FlexFlows } from '../shorthand-css-data.js';
2
+ import type { SimpleShorthandOpener, GetSimpleShorthandOpener, GetShorthandCloser } from '../shorthand-types.js';
3
+
4
+ import { flexDirectionDataType, flexWrapDataType } from '../../css-data-types/index.js';
5
+ import {
6
+ unorderedListShorthandOpener,
7
+ createShorthandOpener,
8
+ shorthandCloserTemplate,
9
+ createShorthandCloser,
10
+ } from '../shorthand-parser-utils.js';
11
+
12
+ // flex-flow
13
+ export const openFlexFlowShorthand: GetSimpleShorthandOpener<FlexFlows> = <V>() =>
14
+ createShorthandOpener({
15
+ prop: 'flex-flow',
16
+ parts: [
17
+ { prop: 'flex-direction', dataType: flexDirectionDataType },
18
+ { prop: 'flex-wrap', dataType: flexWrapDataType },
19
+ ],
20
+ shorthandOpener: (astNodes, api, parts) => unorderedListShorthandOpener(parts)(astNodes, api),
21
+ }) as SimpleShorthandOpener<V, FlexFlows>;
22
+
23
+ export const closeFlexFlowShorthand: GetShorthandCloser<FlexFlows> = <V>() =>
24
+ createShorthandCloser<V, FlexFlows>(shorthandCloserTemplate<FlexFlows>`${'flex-direction'} ${'flex-wrap'}`);
@@ -0,0 +1,79 @@
1
+ import type {
2
+ OpenedShorthand,
3
+ SimpleShorthandOpener,
4
+ SimpleShorthandOpenerInner,
5
+ ShorthandPart,
6
+ GetSimpleShorthandOpener,
7
+ GetShorthandCloser,
8
+ } from '../shorthand-types.js';
9
+
10
+ import { type Flexes, FLEX_KEYWORD_VALUE_MAP } from '../shorthand-css-data.js';
11
+ import {
12
+ flexSingleValueDataType,
13
+ flexGrowDataType,
14
+ flexShrinkDataType,
15
+ flexBasisDataType,
16
+ } from '../../css-data-types/index.js';
17
+ import {
18
+ matchDataType,
19
+ singleKeywordShorthandOpener,
20
+ createShorthandOpener,
21
+ createShorthandCloserTemplateFromParts,
22
+ createShorthandCloser,
23
+ } from '../shorthand-parser-utils.js';
24
+ import { NoMandatoryPartMatchError } from '../shorthand-parser-errors.js';
25
+
26
+ const getFlexShorthandParts = <V>() =>
27
+ [
28
+ { prop: 'flex-grow', dataType: flexGrowDataType, mandatory: true },
29
+ { prop: 'flex-shrink', dataType: flexShrinkDataType },
30
+ { prop: 'flex-basis', dataType: flexBasisDataType },
31
+ ] as ShorthandPart<V, Flexes>[];
32
+
33
+ // flex
34
+ export const openFlexShorthand: GetSimpleShorthandOpener<Flexes> = <V>() =>
35
+ createShorthandOpener({
36
+ prop: 'flex',
37
+ singleKeywordPart: {
38
+ prop: 'flex',
39
+ dataType: flexSingleValueDataType,
40
+ partOpener: singleKeywordShorthandOpener(FLEX_KEYWORD_VALUE_MAP) as SimpleShorthandOpenerInner<V, Flexes>,
41
+ },
42
+ parts: getFlexShorthandParts(),
43
+ shorthandOpener: (astNodes) => {
44
+ const opened: OpenedShorthand<V> = {};
45
+
46
+ if (matchDataType(flexGrowDataType, astNodes, 0)) {
47
+ opened['flex-grow'] = astNodes[0]!;
48
+
49
+ if (astNodes.length > 1) {
50
+ if (matchDataType(flexShrinkDataType, astNodes, 1)) {
51
+ opened['flex-shrink'] = astNodes[1]!;
52
+
53
+ if (astNodes.length > 2) {
54
+ if (matchDataType(flexBasisDataType, astNodes, 2)) {
55
+ opened['flex-basis'] = astNodes[2]!;
56
+ } else {
57
+ throw new NoMandatoryPartMatchError('flex', 'flex-basis');
58
+ }
59
+ }
60
+ } else if (matchDataType(flexBasisDataType, astNodes, 1)) {
61
+ if (astNodes.length < 3) {
62
+ opened['flex-basis'] = astNodes[1]!;
63
+ } else {
64
+ throw new NoMandatoryPartMatchError('flex', 'flex-shrink');
65
+ }
66
+ } else {
67
+ throw new NoMandatoryPartMatchError('flex', `${'flex-shrink'}, ${'flex-basis'}`);
68
+ }
69
+ }
70
+ } else {
71
+ throw new NoMandatoryPartMatchError('flex', 'flex-grow');
72
+ }
73
+
74
+ return opened;
75
+ },
76
+ }) as SimpleShorthandOpener<V, Flexes>;
77
+
78
+ export const closeFlexShorthand: GetShorthandCloser<Flexes> = <V>() =>
79
+ createShorthandCloser<V, Flexes>(createShorthandCloserTemplateFromParts(getFlexShorthandParts()));
@@ -0,0 +1,85 @@
1
+ import type { FontPrefixes, FontSuffixes, Fonts, OpenedFontShorthand } from '../shorthand-css-data.js';
2
+ import type { OpenedShorthand, ShorthandOpener, ShorthandPart } from '../shorthand-types.js';
3
+
4
+ import {
5
+ fontSingleValueDataType,
6
+ fontStyleDataType,
7
+ fontVariantDataType,
8
+ fontWeightDataType,
9
+ fontStretchDataType,
10
+ fontSizeDataType,
11
+ lineHeightDataType,
12
+ fontFamilyDataType,
13
+ COMMON_FONT_PREFIX_NORMAL,
14
+ } from '../../css-data-types/index.js';
15
+ import {
16
+ matchDataType,
17
+ unorderedListShorthandOpener,
18
+ createShorthandOpener,
19
+ shorthandCloserTemplate,
20
+ createShorthandCloser,
21
+ } from '../shorthand-parser-utils.js';
22
+ import { NoMandatoryPartMatchError } from '../shorthand-parser-errors.js';
23
+
24
+ // TODO: Though not directly settable by font, the longhands font-size-adjust and font-kerning are also reset to their initial values.
25
+ // font
26
+ export const openFontShorthand = <V>(): ShorthandOpener<V, Fonts, OpenedFontShorthand<V>> => {
27
+ const fontPrefixShorthandParts: ShorthandPart<V>[] = [
28
+ { prop: 'font-style', dataType: fontStyleDataType, multipleItems: true },
29
+ { prop: 'font-variant', dataType: fontVariantDataType },
30
+ { prop: 'font-weight', dataType: fontWeightDataType },
31
+ { prop: 'font-stretch', dataType: fontStretchDataType },
32
+ ];
33
+ const fontSizeShorthandPart: ShorthandPart<V> = {
34
+ prop: 'font-size',
35
+ dataType: fontSizeDataType,
36
+ mandatory: true,
37
+ };
38
+ const fontSuffixShorthandParts: ShorthandPart<V>[] = [
39
+ fontSizeShorthandPart,
40
+ { prop: 'line-height', dataType: lineHeightDataType },
41
+ {
42
+ prop: 'font-family',
43
+ dataType: fontFamilyDataType,
44
+ multipleItems: true,
45
+ mandatory: true,
46
+ },
47
+ ];
48
+ const openFontShorthandPrefixInner = unorderedListShorthandOpener<V, FontPrefixes>(fontPrefixShorthandParts, {
49
+ commonValue: COMMON_FONT_PREFIX_NORMAL,
50
+ });
51
+ const openFontShorthandSuffixInner = unorderedListShorthandOpener<V, FontSuffixes>(fontSuffixShorthandParts);
52
+
53
+ return createShorthandOpener({
54
+ prop: 'font',
55
+ singleKeywordPart: { prop: 'font', dataType: fontSingleValueDataType },
56
+ parts: fontPrefixShorthandParts.concat(fontSuffixShorthandParts) as ShorthandPart<V, Fonts>[],
57
+ shorthandOpener: (astNodes, api) => {
58
+ let opened: OpenedShorthand<V> = {};
59
+
60
+ const prefixEndPart = fontSizeShorthandPart;
61
+ let prefixEndIndex = -1;
62
+ for (let i = 0; i < astNodes.length; i++) {
63
+ if (matchDataType(prefixEndPart.dataType, astNodes, i)) {
64
+ prefixEndIndex = i;
65
+ break;
66
+ }
67
+ }
68
+ if (prefixEndIndex !== -1) {
69
+ opened = {
70
+ ...openFontShorthandPrefixInner(astNodes.slice(0, prefixEndIndex), api),
71
+ ...openFontShorthandSuffixInner(astNodes.slice(prefixEndIndex), api),
72
+ };
73
+ } else {
74
+ throw new NoMandatoryPartMatchError('font', prefixEndPart.prop);
75
+ }
76
+
77
+ return opened;
78
+ },
79
+ }) as ShorthandOpener<V, Fonts, OpenedFontShorthand<V>>;
80
+ };
81
+
82
+ export const closeFontShorthand = <V>() =>
83
+ createShorthandCloser<V, Fonts, OpenedFontShorthand<V>>(
84
+ shorthandCloserTemplate<Fonts>`${'font-style'} ${'font-variant'} ${'font-weight'} ${'font-stretch'} ${'font-size'} / ${'line-height'} ${'font-family'}`,
85
+ );
@@ -0,0 +1,47 @@
1
+ import type { Gaps } from '../shorthand-css-data.js';
2
+ import type {
3
+ SimpleShorthandOpener,
4
+ ShorthandPart,
5
+ GetSimpleShorthandOpener,
6
+ GetShorthandCloser,
7
+ EvaluatedAst,
8
+ OpenedShorthand,
9
+ } from '../shorthand-types.js';
10
+
11
+ import { lengthPercentageDataType } from '../../css-data-types/index.js';
12
+ import {
13
+ createShorthandOpener,
14
+ createShorthandCloserTemplateFromParts,
15
+ createShorthandCloser,
16
+ } from '../shorthand-parser-utils.js';
17
+
18
+ const getGapShorthandParts = <V>() =>
19
+ [
20
+ {
21
+ prop: 'row-gap',
22
+ dataType: lengthPercentageDataType,
23
+ },
24
+ {
25
+ prop: 'column-gap',
26
+ dataType: lengthPercentageDataType,
27
+ },
28
+ ] as ShorthandPart<V, Gaps>[];
29
+
30
+ function gapOpener<V>(nodes: EvaluatedAst<V>[]): OpenedShorthand<V, 'row-gap' | 'column-gap'> {
31
+ if (nodes.length === 0 || nodes.length > 2) throw new Error('gap shorthand can only have 1 or 2 values');
32
+ return {
33
+ 'row-gap': nodes[0]!,
34
+ 'column-gap': nodes[1] ?? nodes[0]!,
35
+ };
36
+ }
37
+
38
+ // gap
39
+ export const openGapShorthand: GetSimpleShorthandOpener<Gaps> = <V>() =>
40
+ createShorthandOpener({
41
+ prop: 'gap',
42
+ parts: getGapShorthandParts(),
43
+ shorthandOpener: gapOpener,
44
+ }) as SimpleShorthandOpener<V, Gaps>;
45
+
46
+ export const closeGapShorthand: GetShorthandCloser<Gaps> = <V>() =>
47
+ createShorthandCloser<V, Gaps>(createShorthandCloserTemplateFromParts(getGapShorthandParts()));
@@ -0,0 +1,61 @@
1
+ import type { GridAxis, GridAxisLonghands } from '../shorthand-css-data.js';
2
+ import { gridLineDataType, gridLineEndDataType } from '../../css-data-types/index.js';
3
+ import type {
4
+ SimpleShorthandOpener,
5
+ ShorthandPart,
6
+ GetSimpleShorthandOpener,
7
+ GetShorthandCloser,
8
+ EvaluatedAst,
9
+ OpenedShorthand,
10
+ } from '../shorthand-types.js';
11
+ import { createShorthandOpener, createShorthandCloser, shorthandCloserTemplate } from '../shorthand-parser-utils.js';
12
+
13
+ const getGridAxisShorthandParts = <V, A extends GridAxis>(axis: A) =>
14
+ [
15
+ {
16
+ prop: `grid-${axis}-start`,
17
+ dataType: gridLineDataType,
18
+ multipleItems: true,
19
+ },
20
+ {
21
+ prop: `grid-${axis}-end`,
22
+ dataType: gridLineEndDataType,
23
+ multipleItems: true,
24
+ },
25
+ ] as ShorthandPart<V, GridAxisLonghands<A>>[];
26
+
27
+ function openGridAxisShorthand<Axis extends 'row' | 'column', V>(
28
+ axis: Axis,
29
+ valueAst: EvaluatedAst<V>[],
30
+ ): OpenedShorthand<V, GridAxisLonghands<Axis>> {
31
+ const delimiterIndex = valueAst.findIndex((node) => node.value.type === '/');
32
+ const startNodes = delimiterIndex === -1 ? valueAst : valueAst.slice(0, delimiterIndex);
33
+ const endNodes = delimiterIndex === -1 ? [...startNodes] : valueAst.slice(delimiterIndex + 1);
34
+
35
+ return {
36
+ [`grid-${axis}-start`]: startNodes,
37
+ [`grid-${axis}-end`]: endNodes,
38
+ } as OpenedShorthand<V, GridAxisLonghands<Axis>>;
39
+ }
40
+
41
+ const createGridAxisShorthandOpener: <A extends GridAxis>(axis: A) => GetSimpleShorthandOpener<GridAxisLonghands<A>> =
42
+ (axis) =>
43
+ <V>() =>
44
+ createShorthandOpener({
45
+ prop: `grid-${axis}`,
46
+ parts: getGridAxisShorthandParts(axis),
47
+ shorthandOpener: (astNodes) => openGridAxisShorthand(axis, astNodes),
48
+ }) as SimpleShorthandOpener<V>;
49
+
50
+ const createGridAxisShorthandCloser: <A extends GridAxis>(axis: A) => GetShorthandCloser<GridAxisLonghands<A>> =
51
+ (axis) =>
52
+ <V>() =>
53
+ createShorthandCloser<V>(shorthandCloserTemplate`${`grid-${axis}-start`} / ${`grid-${axis}-end`}`);
54
+
55
+ // grid-row
56
+ export const openGridRowShorthand = createGridAxisShorthandOpener('row');
57
+ export const closeGridRowShorthand = createGridAxisShorthandCloser('row');
58
+
59
+ // grid-column
60
+ export const openGridColumnShorthand = createGridAxisShorthandOpener('column');
61
+ export const closeGridColumnShorthand = createGridAxisShorthandCloser('column');
@@ -0,0 +1,40 @@
1
+ import type { GridGaps } from '../shorthand-css-data.js';
2
+ import type {
3
+ SimpleShorthandOpener,
4
+ ShorthandPart,
5
+ GetSimpleShorthandOpener,
6
+ GetShorthandCloser,
7
+ } from '../shorthand-types.js';
8
+
9
+ import { lengthPercentageDataType } from '../../css-data-types/index.js';
10
+ import {
11
+ splitSimpleShorthandOpener,
12
+ unorderedListShorthandOpener,
13
+ createShorthandOpener,
14
+ createShorthandCloserTemplateFromParts,
15
+ createShorthandCloser,
16
+ } from '../shorthand-parser-utils.js';
17
+
18
+ const getGridGapShorthandParts = <V>() =>
19
+ [
20
+ {
21
+ prop: 'grid-row-gap',
22
+ dataType: lengthPercentageDataType,
23
+ partOpener: splitSimpleShorthandOpener(['grid-row-gap', 'grid-column-gap']),
24
+ },
25
+ {
26
+ prop: 'grid-column-gap',
27
+ dataType: lengthPercentageDataType,
28
+ },
29
+ ] as ShorthandPart<V, GridGaps>[];
30
+
31
+ // grid-gap
32
+ export const openGridGapShorthand: GetSimpleShorthandOpener<GridGaps> = <V>() =>
33
+ createShorthandOpener({
34
+ prop: 'grid-gap',
35
+ parts: getGridGapShorthandParts(),
36
+ shorthandOpener: (astNodes, api, parts) => unorderedListShorthandOpener(parts)(astNodes, api),
37
+ }) as SimpleShorthandOpener<V, GridGaps>;
38
+
39
+ export const closeGridGapShorthand: GetShorthandCloser<GridGaps> = <V>() =>
40
+ createShorthandCloser<V, GridGaps>(createShorthandCloserTemplateFromParts(getGridGapShorthandParts()));
@@ -0,0 +1,260 @@
1
+ import type {
2
+ CSSAstNode,
3
+ EvaluatedAst,
4
+ OpenedShorthand,
5
+ SimpleShorthandOpener,
6
+ SimpleShorthandOpenerInner,
7
+ ShorthandPart,
8
+ GetSimpleShorthandOpener,
9
+ ShorthandCloser,
10
+ } from '../shorthand-types.js';
11
+
12
+ import { type SlashNode, createCssValueAST, valueTextNode } from '../../tokenizers/index.js';
13
+ import { codeToEvaluatedAst } from '../shorthands-ast-evaluation.js';
14
+ import { type GridAxis, type Grids, GRID_KEYWORD_VALUE_MAP } from '../shorthand-css-data.js';
15
+ import {
16
+ DataTypeType,
17
+ type PredicateIndexMatch,
18
+ asteriskPredicate,
19
+ findPredicateIndexMatch,
20
+ seperatorPredicate,
21
+ trackSizePredicate,
22
+ gridAutoFlowPredicate,
23
+ gridTemplateAreasDataType,
24
+ gridTemplateRowsDataType,
25
+ gridTemplateColumnsDataType,
26
+ gridAutoFlowDataType,
27
+ gridAutoRowsDataType,
28
+ gridAutoColumnsDataType,
29
+ gridSingleValueDataType,
30
+ GRID_AUTO_FLOW_KEYWORD,
31
+ GRID_AUTO_FLOW_ROW_KEYWORD,
32
+ GRID_AUTO_FLOW_COLUMN_KEYWORD,
33
+ GRID_AUTO_FLOW_DENSE_KEYWORD,
34
+ } from '../../css-data-types/index.js';
35
+ import {
36
+ matchDataType,
37
+ isOpenedInitial,
38
+ singleKeywordShorthandOpener,
39
+ createShorthandOpener,
40
+ getOpenedNode,
41
+ fixAstNodesPositions,
42
+ } from '../shorthand-parser-utils.js';
43
+ import {
44
+ getGridTemplateShorthandParts,
45
+ gridTemplateShorthandOpener,
46
+ closeGridTemplateShorthand,
47
+ } from './grid-template-shorthand.js';
48
+ import { NoMandatoryPartMatchError, CannotCloseGridError } from '../shorthand-parser-errors.js';
49
+
50
+ interface AutoFlow {
51
+ axis: GridAxis;
52
+ dense: boolean;
53
+ }
54
+
55
+ type OpenedGrids<V> = OpenedShorthand<V, Grids>;
56
+ type GridSingleKeywordShorthandOpener<V> = SimpleShorthandOpenerInner<V, Grids>;
57
+ type GridShorthandCloser<V> = ShorthandCloser<V, Grids, OpenedGrids<V>>;
58
+
59
+ const getGridShorthandParts = <V>() =>
60
+ [
61
+ ...getGridTemplateShorthandParts<V>(),
62
+ { prop: 'grid-auto-flow', dataType: gridAutoFlowDataType, multipleItems: true },
63
+ { prop: 'grid-auto-rows', dataType: gridAutoRowsDataType, multipleItems: true },
64
+ { prop: 'grid-auto-columns', dataType: gridAutoColumnsDataType, multipleItems: true },
65
+ ] as ShorthandPart<V, Grids>[];
66
+
67
+ const isSeperator = <V>(astNodes: EvaluatedAst<V>[], index: number) => seperatorPredicate()(astNodes[index]!.value);
68
+
69
+ const getTrackSizeLength = <V>(astNodes: EvaluatedAst<V>[], index: number) =>
70
+ astNodes.length > index
71
+ ? Number(asteriskPredicate(trackSizePredicate)(astNodes[index]!.value, index, astNodes))
72
+ : 0;
73
+
74
+ const getAutoFlowText = (axis: GridAxis, dense = false) =>
75
+ (axis === 'row' ? GRID_AUTO_FLOW_ROW_KEYWORD : GRID_AUTO_FLOW_COLUMN_KEYWORD) +
76
+ (dense ? ` ${GRID_AUTO_FLOW_DENSE_KEYWORD}` : '');
77
+
78
+ const openGridShorthandAutoFlow = <V>(
79
+ axis: GridAxis,
80
+ astNodes: EvaluatedAst<V>[],
81
+ autoFlowMatch: PredicateIndexMatch,
82
+ trackSizeLength: number,
83
+ rowsLength?: number,
84
+ ) => {
85
+ const { index: autoFlowIndex, length: autoFlowLength } = autoFlowMatch;
86
+
87
+ const opened: Partial<OpenedGrids<V>> = {};
88
+ if (axis === 'row') {
89
+ opened['grid-template-columns'] = astNodes.slice(autoFlowLength + trackSizeLength + 1);
90
+ if (trackSizeLength > 0) {
91
+ opened['grid-auto-rows'] = astNodes.slice(autoFlowLength, autoFlowLength + trackSizeLength);
92
+ }
93
+ } else {
94
+ opened['grid-template-rows'] = astNodes.slice(0, rowsLength);
95
+ if (trackSizeLength > 0) {
96
+ opened['grid-auto-columns'] = astNodes.slice(autoFlowIndex + autoFlowLength);
97
+ }
98
+ }
99
+ opened['grid-auto-flow'] = codeToEvaluatedAst(createCssValueAST(getAutoFlowText(axis, autoFlowLength === 2)));
100
+ return opened;
101
+ };
102
+
103
+ const openGridShorthandTemplateRowsSyntax = <V>(astNodes: EvaluatedAst<V>[], autoFlowMatch: PredicateIndexMatch) => {
104
+ const { index: autoFlowIndex, length: autoFlowLength } = autoFlowMatch;
105
+
106
+ if (autoFlowIndex <= 1 || !isSeperator(astNodes, autoFlowIndex - 1)) {
107
+ throw new NoMandatoryPartMatchError('grid', 'grid-auto-flow');
108
+ }
109
+
110
+ const rowsMatch = matchDataType(gridTemplateRowsDataType, astNodes, 0);
111
+ if (!rowsMatch || Number(rowsMatch) !== autoFlowIndex - 1) {
112
+ throw new NoMandatoryPartMatchError('grid', 'grid-template-rows');
113
+ }
114
+
115
+ const trackSizeLength = getTrackSizeLength(astNodes, autoFlowIndex + autoFlowLength);
116
+ if (trackSizeLength !== astNodes.length - autoFlowIndex - autoFlowLength) {
117
+ throw new NoMandatoryPartMatchError('grid', 'grid-auto-flow');
118
+ }
119
+
120
+ return openGridShorthandAutoFlow('column', astNodes, autoFlowMatch, trackSizeLength, Number(rowsMatch));
121
+ };
122
+
123
+ const openGridShorthandTemplateColumnsSyntax = <V>(astNodes: EvaluatedAst<V>[], autoFlowMatch: PredicateIndexMatch) => {
124
+ const { length: autoFlowLength } = autoFlowMatch;
125
+
126
+ const trackSizeLength = getTrackSizeLength(astNodes, autoFlowLength);
127
+ if (!isSeperator(astNodes, autoFlowLength + trackSizeLength)) {
128
+ throw new NoMandatoryPartMatchError('grid', 'grid-auto-flow');
129
+ }
130
+
131
+ const columnsMatch = matchDataType(
132
+ gridTemplateColumnsDataType,
133
+ astNodes,
134
+ autoFlowLength + trackSizeLength,
135
+ DataTypeType.GridTemplateRows,
136
+ );
137
+ if (!columnsMatch || Number(columnsMatch) !== astNodes.length - autoFlowLength - trackSizeLength) {
138
+ throw new NoMandatoryPartMatchError('grid', 'grid-template-columns');
139
+ }
140
+
141
+ return openGridShorthandAutoFlow('row', astNodes, autoFlowMatch, trackSizeLength);
142
+ };
143
+
144
+ // grid
145
+ export const openGridShorthand: GetSimpleShorthandOpener<Grids> = <V>() =>
146
+ createShorthandOpener({
147
+ prop: 'grid',
148
+ singleKeywordPart: {
149
+ prop: 'grid',
150
+ dataType: gridSingleValueDataType,
151
+ partOpener: singleKeywordShorthandOpener(
152
+ GRID_KEYWORD_VALUE_MAP,
153
+ true,
154
+ ) as GridSingleKeywordShorthandOpener<V>,
155
+ },
156
+ parts: getGridShorthandParts(),
157
+ shorthandOpener: (astNodes) => {
158
+ const autoFlowMatch = findPredicateIndexMatch(astNodes, gridAutoFlowPredicate);
159
+
160
+ return (
161
+ autoFlowMatch
162
+ ? autoFlowMatch.index > 0
163
+ ? openGridShorthandTemplateRowsSyntax(astNodes, autoFlowMatch)
164
+ : openGridShorthandTemplateColumnsSyntax(astNodes, autoFlowMatch)
165
+ : gridTemplateShorthandOpener<V>(astNodes)
166
+ ) as OpenedGrids<V>;
167
+ },
168
+ }) as SimpleShorthandOpener<V, Grids>;
169
+
170
+ const getParsedOpenedAutoFlow = <V>(opened: OpenedGrids<V>): AutoFlow => {
171
+ const openedAutoFlow = opened['grid-auto-flow'];
172
+ const openedAutoArray = Array.isArray(openedAutoFlow) ? openedAutoFlow : [openedAutoFlow];
173
+ if (!isOpenedInitial(opened, 'grid-template-areas', gridTemplateAreasDataType) || openedAutoArray.length < 1) {
174
+ throw new CannotCloseGridError();
175
+ }
176
+
177
+ const parsedAutoFlow = openedAutoArray.reduce((autoFlow, { value }) => {
178
+ switch (value.text) {
179
+ case GRID_AUTO_FLOW_ROW_KEYWORD:
180
+ if (autoFlow.axis === undefined) {
181
+ autoFlow.axis = 'row';
182
+ return autoFlow;
183
+ }
184
+ break;
185
+ case GRID_AUTO_FLOW_COLUMN_KEYWORD:
186
+ if (autoFlow.axis === undefined) {
187
+ autoFlow.axis = 'column';
188
+ return autoFlow;
189
+ }
190
+ break;
191
+ case GRID_AUTO_FLOW_DENSE_KEYWORD:
192
+ if (autoFlow.dense === undefined) {
193
+ autoFlow.dense = true;
194
+ return autoFlow;
195
+ }
196
+ break;
197
+ }
198
+ throw new CannotCloseGridError();
199
+ }, {} as Partial<AutoFlow>);
200
+ if (parsedAutoFlow.axis === undefined && parsedAutoFlow.dense === undefined) {
201
+ throw new CannotCloseGridError();
202
+ }
203
+
204
+ return { axis: parsedAutoFlow.axis ?? 'row', dense: !!parsedAutoFlow.dense };
205
+ };
206
+
207
+ const closeGridShorthandAutoFlowSyntax =
208
+ <V>(autoFlow: AutoFlow, isAutoRowsInitial: boolean, isAutoColumnsInitial: boolean): GridShorthandCloser<V> =>
209
+ (opened, api, detachExpression) => {
210
+ const { axis, dense } = autoFlow;
211
+
212
+ if (
213
+ (axis === 'row' &&
214
+ (!isOpenedInitial(opened, 'grid-template-rows', gridTemplateRowsDataType) || !isAutoColumnsInitial)) ||
215
+ (axis === 'column' &&
216
+ (!isOpenedInitial(opened, 'grid-template-columns', gridTemplateColumnsDataType) || !isAutoRowsInitial))
217
+ ) {
218
+ throw new CannotCloseGridError();
219
+ }
220
+
221
+ return [valueTextNode(GRID_AUTO_FLOW_KEYWORD) as CSSAstNode<V>]
222
+ .concat(dense ? [valueTextNode(GRID_AUTO_FLOW_DENSE_KEYWORD)] : [])
223
+ .concat(
224
+ getOpenedNode(opened[axis === 'row' ? 'grid-auto-rows' : 'grid-auto-columns'], api, detachExpression),
225
+ );
226
+ };
227
+
228
+ export const closeGridShorthand =
229
+ <V>(): GridShorthandCloser<V> =>
230
+ (opened, api, detachExpression) => {
231
+ const isAutoRowsInitial = isOpenedInitial(opened, 'grid-auto-rows', gridAutoRowsDataType);
232
+ const isAutoColumnsInitial = isOpenedInitial(opened, 'grid-auto-columns', gridAutoColumnsDataType);
233
+ if (
234
+ isOpenedInitial(opened, 'grid-auto-flow', gridAutoFlowDataType) &&
235
+ isAutoRowsInitial &&
236
+ isAutoColumnsInitial
237
+ ) {
238
+ return closeGridTemplateShorthand<V>()(opened, api, detachExpression);
239
+ }
240
+
241
+ const autoFlow = getParsedOpenedAutoFlow(opened);
242
+
243
+ const closedAutoFlowAst = closeGridShorthandAutoFlowSyntax<V>(
244
+ autoFlow,
245
+ isAutoRowsInitial,
246
+ isAutoColumnsInitial,
247
+ )(opened, api, detachExpression);
248
+ const closedTemplateAxisAst = getOpenedNode(
249
+ opened[autoFlow.axis === 'row' ? 'grid-template-columns' : 'grid-template-rows'],
250
+ api,
251
+ detachExpression,
252
+ );
253
+ const slashNode = { ...valueTextNode('/'), type: '/' } as SlashNode;
254
+ return fixAstNodesPositions(
255
+ autoFlow.axis === 'row'
256
+ ? closedAutoFlowAst.concat(slashNode).concat(closedTemplateAxisAst)
257
+ : closedTemplateAxisAst.concat(slashNode).concat(closedAutoFlowAst),
258
+ api,
259
+ );
260
+ };