Skip to content

Commit

Permalink
docs(guidelines): remove old guidelines from lite readme
Browse files Browse the repository at this point in the history
  • Loading branch information
ByScripts committed Sep 13, 2024
1 parent 68f76b4 commit c5959be
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 247 deletions.
211 changes: 2 additions & 209 deletions @xen-orchestra/lite/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,213 +5,6 @@
- `yarn`
- `yarn dev`

## Conventions
## Guidelines

### File names

| Type | Format | Exemple |
| ---------- | ---------------------------------------- | ----------------------------------- |
| Component | `components/<PascalCase>.vue` | `components/FooBar.vue` |
| View | `views/<PascalCase>View.vue` | `views/FooBarView.vue` |
| Composable | `composables/<kebab-case>.composable.ts` | `composables/foo-bar.composable.ts` |
| Store | `stores/<kebab-case>.store.ts` | `stores/foo-bar.store.ts` |
| Other | `libs/<kebab-case>.ts` | `libs/foo-bar.ts` |

For components and views, prepend the subdirectories names to the resulting filename.

Example: `components/foo/bar/FooBarBaz.vue`

### Vue Components

Use Vue Single File Components (`*.vue`).

Insert blocks in the following order: `template`, `script` then `style`.

#### Template

Use HTML.

If your component only has one root element, add the component name as a class.

```vue
<!-- MyComponent.vue -->
<template>
<div class="my-component">...</div>
</template>
```

#### Script

Use composition API + TypeScript + `setup` attribute (`<script lang="ts" setup>`).

Note: When reading Vue official doc, don't forget to set "API Preference" toggle (in the upper left) on "Composition".

```vue
<script lang="ts" setup>
import { computed, ref } from 'vue'
const props = defineProps<{
greetings: string
}>()
const firstName = ref('')
const lastName = ref('')
const fullName = computed(() => `${props.greetings} ${firstName.value} ${lastName.value}`)
</script>
```

#### CSS

Always use `scoped` attribute (`<style scoped>`).

Nested rules are allowed.

Vue variables can be interpolated with `v-bind`.

```vue
<script lang="ts" setup>
import { ref } from 'vue'
const fontSize = ref('2rem')
</script>
<style scoped>
.my-item {
.nested {
font-size: v-bind(fontSize);
}
}
</style>
```

### Icons

This project is using Font Awesome 6 Free.

Icons can be displayed with the `UiIcon` component.

Passing `undefined` as `icon` prop will disable the component (no need to use an additional `v-if` condition).

Use the `busy` prop to display a loader icon.

```vue
<template>
<div>
<UiIcon :icon="faDisplay" />
</div>
</template>
<script lang="ts" setup>
import UiIcon from '@/components/ui/icon/UiIcon.vue'
import { faDisplay } from '@fortawesome/free-solid-svg-icons'
</script>
```

#### Font weight <=> Style name

Here is the equivalent between font weight and style name.

| Style name | Font weight |
| ---------- | ----------- |
| Solid | 900 |
| Regular | 400 |

### CSS

Always use `rem` unit (`1rem` = `10px`)

### Store

Use Pinia store with setup function.

State are `ref`

Getters are `computed`

Actions/Mutations are simple functions

#### Naming convention

For a `foobar` store, create a `store/foobar.store.ts` then use `defineStore('foobar', setupFunc)`

#### Example

```typescript
import { computed, ref } from 'vue'

export const useFoobarStore = defineStore('foobar', () => {
const aStateVar = ref(0)
const otherStateVar = ref(0)
const aGetter = computed(() => aStateVar.value * 2)
const anAction = () => (otherStateVar.value += 10)

return {
aStateVar,
otherStateVar,
aGetter,
anAction,
}
})
```

### I18n

Internationalization of the app is done with [Vue-i18n](https://vue-i18n.intlify.dev/).

Locale files are located in `src/locales` directory.

Source of truth is `en-US.json` file.

To quickly check if there are missing translations in other locale files, open `main.ts` and check the `messages`
property of `createI18n()` for TypeScript error.

#### Example

```json
{
"hello": "Hello",
"hello_name": "Hello {name}",
"hello_linked": "@:hello_name how are you?",
"hello_plural": "No hello | Hello to you | Hello to {count} persons"
}
```

```html
<!-- String -->

<p>{{ $t("hello") }}</p>
<!-- Hello -->
<p>{{ $t("hello_name", { name: "World" }) }}</p>
<!-- Hello World -->
<p>{{ $t("hello_linked", { name: "World" }) }}</p>
<!-- Hello World how are you? -->
<p>{{ $tc("hello_plural", 0) }}</p>
<!-- No hello -->
<p>{{ $tc("hello_plural", 1) }}</p>
<!-- Hello to you -->
<p>{{ $tc("hello_plural", 4) }}</p>
<!-- Hello to 4 persons -->

<!-- Date and time -->

<p>{{ $d(date, "date_short") }}</p>
<!-- 9/10/2022 -->
<p>{{ $d(date, "date_medium") }}</p>
<!-- Sep 10, 2022 -->
<p>{{ $d(date, "date_long") }}</p>
<!-- September 10, 2022 -->
<p>{{ $d(date, "datetime_short") }}</p>
<!-- 9/10/2022, 06:30 PM -->
<p>{{ $d(date, "datetime_medium") }}</p>
<!-- Sep 10, 2022, 06:30 PM -->
<p>{{ $d(date, "datetime_long") }}</p>
<!-- September 10, 2022 at 06:30 PM -->
<p>{{ $d(date, "time") }}</p>
<!-- 06:30 PM -->

<!-- Number -->

<p>{{ $n(1234567.898765) }}</p>
<!-- 1,234,567.899 -->
```
Please follow the guidelines from the `@xen-orchestra/web-core/guidelines` directory.
58 changes: 20 additions & 38 deletions @xen-orchestra/web-core/docs/guidelines/component definition.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,17 @@ Lexicon:

## Components SHOULD be named according to their name in the DS (Design System)

## Components SHOULD be kept short and be split into multiple subcomponents if necessary, stored in the same directory

✅ Good

```
/components/
/square/
/Square.vue
/SquareIcon.vue
```

## Components from DS MUST start with an HTML comment containing the implemented version

In the form `v<x>.<y>` (`z` is reserved to DS versioning)
Expand All @@ -35,6 +46,8 @@ In the form `v<x>.<y>` (`z` is reserved to DS versioning)

## Subcomponents MUST NOT have a version number

If a component from the DS is split into multiple subcomponents, only the main component will have a version number

## Components MUST be stored in their own directory

❌ Bad
Expand All @@ -47,20 +60,11 @@ In the form `v<x>.<y>` (`z` is reserved to DS versioning)

## Component tags MUST follow `template`, `script` then `style` order, separated with an empty line

## Components SHOULD be kept short and be split into multiple Subcomponents if necessary, stored in the same directory

✅ Good

```
/components/
/square/
/Square.vue
/SquareIcon.vue
```

## Class names MUST use kebab-case

## Component root element MUST have a class name based on the component name, prefixed with `vts-`
## Component root element's class name MUST be named after the component name, prefixed with `vts-`

If no style is applied to the root element, the class name will be omitted

❌ Bad

Expand Down Expand Up @@ -101,7 +105,7 @@ In the form `v<x>.<y>` (`z` is reserved to DS versioning)
```vue
<template>
<div class="vts-square">
<Icon :icon="faSmile" class="vts-square-icon" />
<Icon :icon="faSmile" class="square-icon" />
<div class="component-label"><slot /></div>
</div>
</template>
Expand Down Expand Up @@ -186,7 +190,7 @@ With meaningful class names + scoped styles, in most cases it will not be necess
</template>
```

## Component MUST use `defineSlots` when another slot than `default` is used or slot has props
## Component MUST use `defineSlots` when slots are used

❌ Bad

Expand All @@ -213,36 +217,14 @@ With meaningful class names + scoped styles, in most cases it will not be necess
<template>
<div class="vts-foobar">
<slot />
</div>
</template>
```

```vue
<template>
<div class="vts-foobar">
<slot foo="bar" />
</div>
</template>
<script lang="ts" setup>
defineSlots<{
default(props: { foo: string }): any
}>()
</script>
```

```vue
<template>
<div class="vts-foobar">
<slot />
<slot name="footer" />
<slot name="footer" foo="bar" />
</div>
</template>
<script lang="ts" setup>
defineSlots<{
default(): any
footer(): any
footer(props: { foo: string }): any
}>()
</script>
```
Expand Down
26 changes: 26 additions & 0 deletions @xen-orchestra/web-core/docs/guidelines/icons.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Icons

XO Lite / 6 / Core projects are using Font Awesome 6 Free.

Icons can be displayed with the `UiIcon` component.

The component takes an `icon` prop that should be an icon object imported from `@fortawesome/free-solid-svg-icons` or `@fortawesome/free-regular-svg-icons`.

If the `icon` prop is `undefined`, then the component will be ignored (no need to use an additional `v-if` condition).

Use the `busy` prop to display a loader icon.

## Example

```vue
<template>
<div>
<UiIcon :icon="faDisplay" />
</div>
</template>
<script lang="ts" setup>
import UiIcon from '@/components/ui/icon/UiIcon.vue'
import { faDisplay } from '@fortawesome/free-solid-svg-icons'
</script>
```
33 changes: 33 additions & 0 deletions @xen-orchestra/web-core/docs/guidelines/stores.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Stores

Stores definition must use Pinia setup function.

State are `ref`

Getters are `computed`

Actions/Mutations are simple functions

## Naming convention

For a `foobar` store, create a `store/foobar.store.ts` then use `defineStore('foobar', setupFunc)`

## Example

```typescript
import { computed, ref } from 'vue'

export const useFoobarStore = defineStore('foobar', () => {
const aStateVar = ref(0)
const otherStateVar = ref(0)
const aGetter = computed(() => aStateVar.value * 2)
const anAction = () => (otherStateVar.value += 10)

return {
aStateVar,
otherStateVar,
aGetter,
anAction,
}
})
```
4 changes: 4 additions & 0 deletions @xen-orchestra/web/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,7 @@
4. Start the project: `yarn dev`
5. Generate a token from your XO 5 instance
6. Go to http://localhost:5173/#/dev/token and paste the token

## Guidelines

Please follow the guidelines from the `@xen-orchestra/web-core/guidelines` directory.

0 comments on commit c5959be

Please sign in to comment.