Add complete Acai development documentation
- CLAUDE.md: expanded with critical rules, hook syntax, DB conventions, web-base endpoint - docs/modular-system.md: modules, general sections, global vars, multiv2 - docs/builder-fields.md: all field types, c-if/c-for/c-class, c-form, built-in components - docs/twig-filters.md: get, hook, module, queryDB, imagec, translate, raw, etc. - docs/hooks-and-api.md: PHP hooks, CmsApi CRUD, table schemas, field formats - docs/css-js-conventions.md: Tailwind, BEM, CSS vars, Vue 3 integration, CmsApi JS Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
101
docs/css-js-conventions.md
Normal file
101
docs/css-js-conventions.md
Normal file
@@ -0,0 +1,101 @@
|
||||
# CSS & JavaScript Conventions
|
||||
|
||||
## CSS
|
||||
|
||||
### Tailwind First
|
||||
|
||||
Use Tailwind CSS as the primary styling method. Only use custom CSS when Tailwind is insufficient.
|
||||
|
||||
```html
|
||||
<!-- Good: Tailwind classes -->
|
||||
<div class="flex items-center gap-4 p-6 bg-white rounded-lg shadow-md">
|
||||
<h2 class="text-2xl font-bold text-gray-900">Title</h2>
|
||||
</div>
|
||||
|
||||
<!-- Custom CSS only when needed (animations, complex selectors, etc.) -->
|
||||
```
|
||||
|
||||
### BEM for Custom CSS
|
||||
|
||||
When custom CSS is needed, scope everything under a root class using BEM naming:
|
||||
|
||||
```css
|
||||
/* Root class in kebab-case */
|
||||
.hero-section { }
|
||||
.hero-section__title { }
|
||||
.hero-section__image { }
|
||||
.hero-section--dark { }
|
||||
```
|
||||
|
||||
Never use global classes without a module prefix.
|
||||
|
||||
### CSS Variables
|
||||
|
||||
Acai provides theme variables:
|
||||
|
||||
```css
|
||||
var(--main-color) /* Primary brand color */
|
||||
var(--main-color-light) /* Lighter variant */
|
||||
var(--main-color-dark) /* Darker variant */
|
||||
```
|
||||
|
||||
### Utility Classes (Built-in)
|
||||
|
||||
| Class | Description |
|
||||
|-------|-------------|
|
||||
| `transition3s` | 0.3s smooth transition |
|
||||
| `click-a-child` | Makes parent clickable via child `<a>` tag |
|
||||
| `line-clamp2` / `line-clamp3` / `line-clamp5` | Text truncation with ellipsis |
|
||||
| `filter-white` | CSS filter to make images/icons white |
|
||||
| `lazyload` | Lazy loading (use with `data-src`) |
|
||||
|
||||
|
||||
## JavaScript
|
||||
|
||||
### Module Scripts (`script.js`)
|
||||
|
||||
Keep JavaScript scoped to the module. Use `section_id` for targeting:
|
||||
|
||||
```js
|
||||
// Scope to this module instance
|
||||
const section = document.getElementById('{{ section_id }}');
|
||||
if (section) {
|
||||
const buttons = section.querySelectorAll('.btn');
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### CmsApi (Client-Side)
|
||||
|
||||
```js
|
||||
// Call a hook
|
||||
CmsApi.hook('/hooks/module_id/', { action: 'getData', id: 123 }, function(response) {
|
||||
console.log(response);
|
||||
});
|
||||
```
|
||||
|
||||
### Vue 3 Integration
|
||||
|
||||
For complex interactivity, use Vue 3 via CDN with Composition API:
|
||||
|
||||
```html
|
||||
<div id="app-{{ section_id }}">
|
||||
<p>${ message }</p>
|
||||
<button @click="increment">${ count }</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const { createApp, ref } = Vue;
|
||||
createApp({
|
||||
delimiters: ['${', '}'], // Avoid conflict with Twig {{ }}
|
||||
setup() {
|
||||
const message = ref('Hello');
|
||||
const count = ref(0);
|
||||
const increment = () => count.value++;
|
||||
return { message, count, increment };
|
||||
}
|
||||
}).mount('#app-{{ section_id }}');
|
||||
</script>
|
||||
```
|
||||
|
||||
**Important:** Use `'${'` and `'}'` as Vue delimiters to avoid conflicts with Twig's `{{ }}` syntax.
|
||||
Reference in New Issue
Block a user