@aerogel/core 0.0.0-next.9a02fcd3bcf698211dd7a71d4c48257c96dd7832 → 0.0.0-next.a3194a101ceda87a7033fa5e283e046bad6f4bfc

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@aerogel/core",
3
3
  "description": "The Lightest Solid",
4
- "version": "0.0.0-next.9a02fcd3bcf698211dd7a71d4c48257c96dd7832",
4
+ "version": "0.0.0-next.a3194a101ceda87a7033fa5e283e046bad6f4bfc",
5
5
  "main": "dist/aerogel-core.cjs.js",
6
6
  "module": "dist/aerogel-core.esm.js",
7
7
  "types": "dist/aerogel-core.d.ts",
@@ -13,6 +13,7 @@
13
13
  'ring-1 ring-red-500': $input?.errors,
14
14
  }"
15
15
  />
16
+ <AGHeadlessInputDescription />
16
17
  <div class="absolute bottom-0 left-0 translate-y-full">
17
18
  <AGHeadlessInputError class="mt-1 text-sm text-red-500" />
18
19
  </div>
@@ -26,6 +27,7 @@ import { useInputProps } from '@/components/headless/forms/AGHeadlessInput';
26
27
  import type { IAGHeadlessInput } from '@/components/headless/forms/AGHeadlessInput';
27
28
 
28
29
  import AGHeadlessInput from '../headless/forms/AGHeadlessInput.vue';
30
+ import AGHeadlessInputDescription from '../headless/forms/AGHeadlessInputDescription.vue';
29
31
  import AGHeadlessInputError from '../headless/forms/AGHeadlessInputError.vue';
30
32
  import AGHeadlessInputInput from '../headless/forms/AGHeadlessInputInput.vue';
31
33
  import AGHeadlessInputLabel from '../headless/forms/AGHeadlessInputLabel.vue';
@@ -7,6 +7,7 @@ export interface IAGHeadlessInput {
7
7
  id: string;
8
8
  name: ComputedRef<string | null>;
9
9
  label: ComputedRef<string | null>;
10
+ description: ComputedRef<string | boolean | null>;
10
11
  value: ComputedRef<string | number | boolean | null>;
11
12
  errors: DeepReadonly<Ref<string[] | null>>;
12
13
  update(value: string | number | boolean | null): void;
@@ -15,6 +16,7 @@ export interface IAGHeadlessInput {
15
16
  export const inputProps = {
16
17
  name: stringProp(),
17
18
  label: stringProp(),
19
+ description: stringProp(),
18
20
  };
19
21
 
20
22
  export function useInputProps(): typeof inputProps {
@@ -33,6 +33,7 @@ const api: IAGHeadlessInput = {
33
33
  id: `input-${uuid()}`,
34
34
  name: computed(() => props.name),
35
35
  label: computed(() => props.label),
36
+ description: computed(() => props.description),
36
37
  value: computed(() => {
37
38
  if (form && props.name) {
38
39
  return form.getFieldValue(props.name) as string | number | boolean | null;
@@ -0,0 +1,28 @@
1
+ <template>
2
+ <slot :id="`${input.id}-description`">
3
+ <AGMarkdown
4
+ v-if="show"
5
+ v-bind="$attrs"
6
+ :id="`${input.id}-description`"
7
+ :text="text"
8
+ />
9
+ </slot>
10
+ </template>
11
+
12
+ <script setup lang="ts">
13
+ import { computed } from 'vue';
14
+
15
+ import { injectReactiveOrFail } from '@/utils/vue';
16
+
17
+ import AGMarkdown from '../../lib/AGMarkdown.vue';
18
+ import type { IAGHeadlessInput } from './AGHeadlessInput';
19
+
20
+ defineOptions({ inheritAttrs: false });
21
+
22
+ const input = injectReactiveOrFail<IAGHeadlessInput>(
23
+ 'input',
24
+ '<AGHeadlessInputDescription> must be a child of a <AGHeadlessInput>',
25
+ );
26
+ const text = computed(() => (typeof input.description === 'string' ? input.description : ''));
27
+ const show = computed(() => !!input.description);
28
+ </script>
@@ -6,7 +6,9 @@
6
6
  :type="type"
7
7
  :value="value"
8
8
  :aria-invalid="input.errors ? 'true' : 'false'"
9
- :aria-describedby="input.errors ? `${input.id}-error` : undefined"
9
+ :aria-describedby="
10
+ input.errors ? `${input.id}-error` : input.description ? `${input.id}-description` : undefined
11
+ "
10
12
  :checked="checked"
11
13
  @input="update"
12
14
  >
@@ -3,6 +3,7 @@ export * from './AGHeadlessSelect';
3
3
  export * from './AGHeadlessSelectOption';
4
4
  export { default as AGHeadlessButton } from './AGHeadlessButton.vue';
5
5
  export { default as AGHeadlessInput } from './AGHeadlessInput.vue';
6
+ export { default as AGHeadlessInputDescription } from './AGHeadlessInputDescription.vue';
6
7
  export { default as AGHeadlessInputError } from './AGHeadlessInputError.vue';
7
8
  export { default as AGHeadlessInputInput } from './AGHeadlessInputInput.vue';
8
9
  export { default as AGHeadlessInputLabel } from './AGHeadlessInputLabel.vue';
@@ -3,7 +3,7 @@
3
3
  </template>
4
4
 
5
5
  <script setup lang="ts">
6
- import { computed, h } from 'vue';
6
+ import { computed, h, useAttrs } from 'vue';
7
7
 
8
8
  import { renderMarkdown } from '@/utils/markdown';
9
9
  import { booleanProp, objectProp, stringProp } from '@/utils/vue';
@@ -17,6 +17,7 @@ const props = defineProps({
17
17
  text: stringProp(),
18
18
  });
19
19
 
20
+ const attrs = useAttrs();
20
21
  const markdown = computed(() => props.text ?? (props.langKey && translate(props.langKey, props.langParams ?? {})));
21
22
  const html = computed(() => {
22
23
  if (!markdown.value) {
@@ -32,5 +33,9 @@ const html = computed(() => {
32
33
  return renderedHtml;
33
34
  });
34
35
  const root = () =>
35
- h(props.as ?? (props.inline ? 'span' : 'div'), { class: props.inline ? '' : 'prose', innerHTML: html.value });
36
+ h(props.as ?? (props.inline ? 'span' : 'div'), {
37
+ class: props.inline ? '' : 'prose',
38
+ innerHTML: html.value,
39
+ ...attrs,
40
+ });
36
41
  </script>
@@ -10,6 +10,8 @@ const builtInDirectives: Record<string, Directive> = {
10
10
  'measure': measure,
11
11
  };
12
12
 
13
+ export * from './measure';
14
+
13
15
  export default definePlugin({
14
16
  install(app, options) {
15
17
  const directives = {
@@ -1,12 +1,21 @@
1
1
  import { defineDirective } from '@/utils/vue';
2
2
 
3
+ export interface ElementSize {
4
+ width: number;
5
+ height: number;
6
+ }
7
+
8
+ export type MeasureDirectiveListener = (size: ElementSize) => unknown;
9
+
3
10
  export default defineDirective({
4
- mounted(element: HTMLElement, { value }: { value?: () => unknown }) {
11
+ mounted(element: HTMLElement, { value }) {
12
+ const listener = typeof value === 'function' ? (value as MeasureDirectiveListener) : null;
5
13
  const sizes = element.getBoundingClientRect();
6
14
 
15
+ // TODO guard with modifiers.css once typed properly
7
16
  element.style.setProperty('--width', `${sizes.width}px`);
8
17
  element.style.setProperty('--height', `${sizes.height}px`);
9
18
 
10
- value?.();
19
+ listener?.({ width: sizes.width, height: sizes.height });
11
20
  },
12
21
  });
package/src/main.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from './bootstrap';
2
2
  export * from './components';
3
+ export * from './directives';
3
4
  export * from './errors';
4
5
  export * from './forms';
5
6
  export * from './jobs';