Skip to content

Commit

Permalink
fix(SSR): apply lazy ID & browser check for SSR render (#290)
Browse files Browse the repository at this point in the history
  • Loading branch information
smithoo authored Nov 21, 2024
1 parent dd444b0 commit b78acd4
Show file tree
Hide file tree
Showing 16 changed files with 54 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
:checked="isChecked(option)"
:dense="dense"
:disabled="computedDisabled"
:id="`${computedId}-${optionIds[index]}`"
:id="`${computedId}-${index}`"
:label="getOptionLabel(option)"
:name="name"
:readonly="computedReadonly"
Expand Down Expand Up @@ -231,12 +231,9 @@ export default defineComponent({
checkboxRefs.value[0]?.blur();
}
const optionIds = computed(() => options.value.map(() => utils.string.createID()));
return {
computedId,
checkboxRefs,
optionIds,
classObj,
computedColorScheme,
computedState,
Expand Down
1 change: 1 addition & 0 deletions packages/vlossom/src/components/vs-footer/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ export interface VsFooterStyleSet {
height?: string;
padding?: string;
width?: string;
zIndex?: string;
}
1 change: 1 addition & 0 deletions packages/vlossom/src/components/vs-header/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ export interface VsHeaderStyleSet {
height?: string;
padding?: string;
width?: string;
zIndex?: string;
}
5 changes: 1 addition & 4 deletions packages/vlossom/src/components/vs-radio-set/VsRadioSet.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
:checked="isChecked(option)"
:dense="dense"
:disabled="computedDisabled"
:id="`${computedId}-${optionIds[index]}`"
:id="`${computedId}-${index}`"
:label="getOptionLabel(option)"
:name="name"
:readonly="computedReadonly"
Expand Down Expand Up @@ -188,12 +188,9 @@ export default defineComponent({
radioRefs.value[0]?.blur();
}
const optionIds = computed(() => options.value.map(() => utils.string.createID()));
return {
computedId,
radioRefs,
optionIds,
classObj,
computedColorScheme,
computedState,
Expand Down
1 change: 0 additions & 1 deletion packages/vlossom/src/components/vs-table/VsTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
<template #check>
<vs-checkbox-node
class="vs-table-select vs-select-all"
:id="utils.string.createID()"
type="checkbox"
:color-scheme="computedColorScheme"
:indeterminate="!isSelectedAll && selectedItems.length > 0"
Expand Down
1 change: 0 additions & 1 deletion packages/vlossom/src/components/vs-table/VsTableBody.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
>
<template #check>
<vs-checkbox-node
:id="element.id"
type="checkbox"
:color-scheme="colorScheme"
:checked="isSelected(element.id)"
Expand Down
1 change: 1 addition & 0 deletions packages/vlossom/src/composables/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export * from './input-form-composable';
export * from './input-modifier-composable';
export * from './input-option-composable';
export * from './layout-composable';
export * from './lazy-id-composable';
export * from './overlay-composable';
export * from './responsive-composable';
export * from './scroll-lock-composable';
Expand Down
5 changes: 2 additions & 3 deletions packages/vlossom/src/composables/input-composable.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ComputedRef, Ref, computed, nextTick, onMounted, ref, watch } from 'vue';
import { useLazyId } from '@/composables';
import { useInputForm } from './input-form-composable';
import { UIState } from '@/declaration';
import { utils } from '@/utils';

import type { StateMessage, InputComponentParams } from '@/declaration';

Expand All @@ -21,8 +21,7 @@ export function useInput<T = unknown>(ctx: any, inputParams: InputComponentParam
callbacks = {},
} = inputParams;

const innerId = utils.string.createID();
const computedId = computed(() => id.value || innerId);
const { computedId } = useLazyId(id);

const changed = ref(false);
const isInitialized = ref(false);
Expand Down
10 changes: 8 additions & 2 deletions packages/vlossom/src/composables/input-form-composable.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Ref, inject, onBeforeMount, onBeforeUnmount, watch } from 'vue';
import { Ref, inject, onMounted, onBeforeUnmount, watch } from 'vue';
import { VS_FORM, VsFormProvide } from '@/declaration';
import { useFormProvide } from './form-provide-composable';

Expand Down Expand Up @@ -27,11 +27,17 @@ export function useInputForm(

watch(clearFlag, clear);

onBeforeMount(() => {
onMounted(() => {
updateChanged(id.value, changed.value);
updateValid(id.value, valid.value);
});

watch(id, (newId, oldId) => {
removeFromForm(oldId);
updateChanged(newId, changed.value);
updateValid(newId, valid.value);
});

onBeforeUnmount(() => {
removeFromForm(id.value);
});
Expand Down
17 changes: 17 additions & 0 deletions packages/vlossom/src/composables/lazy-id-composable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { computed, onMounted, Ref, ref } from 'vue';
import { utils } from '@/utils';

// This composable is used to generate a unique ID for SSR components
export function useLazyId(id: Ref<string>) {
const innerId = ref('');
const computedId = computed(() => id.value || innerId.value);

onMounted(() => {
innerId.value = utils.string.createID();
});

return {
innerId,
computedId,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
<script lang="ts">
import { computed, defineComponent, nextTick, PropType, Ref, ref, toRefs, watch } from 'vue';
import { ColorScheme, UIState, VsNode } from '@/declaration';
import { useColorScheme, useStateClass, useStyleSet } from '@/composables';
import { useColorScheme, useLazyId, useStateClass, useStyleSet } from '@/composables';
import { utils } from '@/utils';
import { VsCheckboxNodeStyleSet } from './types';
Expand Down Expand Up @@ -70,8 +70,7 @@ export default defineComponent({
'vs-indeterminate': indeterminate.value,
}));
const innerId = utils.string.createID();
const computedId = computed(() => id.value || innerId);
const { computedId } = useLazyId(id);
function toggle(event: Event) {
emit('change', event);
Expand Down
2 changes: 1 addition & 1 deletion packages/vlossom/src/nodes/vs-focus-trap/VsFocusTrap.vue
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ export default defineComponent({
return null;
}
const vNodes = slots.default().filter((vnode) => vnode.type !== Comment);
const vNodes = slots.default();
if (vNodes.length !== 1) {
utils.log.error('vs-focus-trap', 'FocusTrap can only contain one child');
Expand Down
5 changes: 2 additions & 3 deletions packages/vlossom/src/nodes/vs-radio-node/VsRadioNode.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<script lang="ts">
import { computed, defineComponent, PropType, Ref, ref, toRefs } from 'vue';
import { ColorScheme, UIState, VsNode } from '@/declaration';
import { useColorScheme, useStateClass, useStyleSet } from '@/composables';
import { useColorScheme, useLazyId, useStateClass, useStyleSet } from '@/composables';
import { utils } from '@/utils';
import { VsRadioNodeStyleSet } from './types';
Expand Down Expand Up @@ -68,8 +68,7 @@ export default defineComponent({
'vs-readonly': readonly.value,
}));
const innerId = utils.string.createID();
const computedId = computed(() => id.value || innerId);
const { computedId } = useLazyId(id);
function toggle(event: Event) {
emit('change', event);
Expand Down
1 change: 1 addition & 0 deletions packages/vlossom/src/styles/variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ $variables: (
font-size-xl: 1.9rem,

// radius
radius-ratio: 1,
radius-xs: 0.2rem,
radius-sm: 0.5rem,
radius: 0.8rem,
Expand Down
3 changes: 3 additions & 0 deletions packages/vlossom/src/utils/dom.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
export const domUtil = {
isBrowser(): boolean {
return typeof window !== 'undefined';
},
getClientRect(element: HTMLElement): DOMRect {
return element.getBoundingClientRect();
},
Expand Down
17 changes: 13 additions & 4 deletions packages/vlossom/src/vlossom-framework.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,29 @@
import { store } from './stores';
import * as vsPlugins from './plugins';
import { utils } from './utils';

import type { App } from 'vue';
import type { VlossomOptions, VsComponent, VsNode } from '@/declaration';
import type { ToastPlugin, ConfirmPlugin } from './plugins';

export class Vlossom {
constructor(options?: VlossomOptions) {
const { colorScheme = {}, styleSet = {}, theme = 'light', radiusRatio = 1 } = options || {};
const {
colorScheme = {},
styleSet = {},
theme = 'light',
radiusRatio = 1,
detectOSTheme = false,
} = options || {};

this.theme = (this.getDefaultTheme(options) as 'light' | 'dark') || theme;
store.option.setGlobalColorScheme(colorScheme);
store.option.registerStyleSet(styleSet);
store.option.setGlobalRadiusRatio(radiusRatio);
if (utils.dom.isBrowser()) {
this.theme = (this.getDefaultTheme(options) as 'light' | 'dark') || theme;
store.option.setGlobalRadiusRatio(radiusRatio);
}

if (options?.detectOSTheme) {
if (utils.dom.isBrowser() && detectOSTheme) {
const mediaQueryList = window.matchMedia('(prefers-color-scheme: dark)');
mediaQueryList.addEventListener('change', (event) => {
this.theme = event.matches ? 'dark' : 'light';
Expand Down

0 comments on commit b78acd4

Please sign in to comment.