@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/dist/aerogel-core.cjs.js +1 -1
- package/dist/aerogel-core.cjs.js.map +1 -1
- package/dist/aerogel-core.d.ts +45 -4
- package/dist/aerogel-core.esm.js +1 -1
- package/dist/aerogel-core.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/components/forms/AGInput.vue +2 -0
- package/src/components/headless/forms/AGHeadlessInput.ts +2 -0
- package/src/components/headless/forms/AGHeadlessInput.vue +1 -0
- package/src/components/headless/forms/AGHeadlessInputDescription.vue +28 -0
- package/src/components/headless/forms/AGHeadlessInputInput.vue +3 -1
- package/src/components/headless/forms/index.ts +1 -0
- package/src/components/lib/AGMarkdown.vue +7 -2
- package/src/directives/index.ts +2 -0
- package/src/directives/measure.ts +11 -2
- package/src/main.ts +1 -0
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.
|
|
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="
|
|
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'), {
|
|
36
|
+
h(props.as ?? (props.inline ? 'span' : 'div'), {
|
|
37
|
+
class: props.inline ? '' : 'prose',
|
|
38
|
+
innerHTML: html.value,
|
|
39
|
+
...attrs,
|
|
40
|
+
});
|
|
36
41
|
</script>
|
package/src/directives/index.ts
CHANGED
|
@@ -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 }
|
|
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
|
-
|
|
19
|
+
listener?.({ width: sizes.width, height: sizes.height });
|
|
11
20
|
},
|
|
12
21
|
});
|