Skip to content

Commit

Permalink
Update developer documentation for core API changes.
Browse files Browse the repository at this point in the history
  • Loading branch information
rtibbles committed Oct 25, 2024
1 parent 86df36c commit 5b50afb
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 73 deletions.
2 changes: 1 addition & 1 deletion docs/dataflow/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ In order to access a particular REST API endpoint, a Javascript Resource has to
:caption: channel.js
:emphasize-lines: 5
import { Resource } from 'kolibri.lib.apiResource';
import { Resource } from 'kolibri/apiResource';
export default new Resource({
name: 'channel',
Expand Down
43 changes: 11 additions & 32 deletions docs/frontend_architecture/core.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,48 +2,30 @@ Shared core functionality
=========================


Kolibri provides a set of shared "core" functionality – including components, styles, and helper logic, and libraries – which can be re-used across apps and plugins.
Kolibri provides a set of shared "core" functionality – including components, styles, and helper logic, and libraries – which can be re-used across apps and plugins. This forms a public API that others may depend on, so we keep it limited to ensure we can continue to support it.

For code that needs to be reused across two plugins, it is recommended to put it in the `kolibri-common` package instead. This will allow easy reuse, but without expanding our API and increasing the number of things we potentially have to support for external users.

JS libraries and Vue components
-------------------------------

The following libraries and components are available globally, in all module code:
The following libraries and components are available for import, in all module code, without need for bundling, e.g.:

- ``vue`` - the Vue.js object
- ``vuex`` - the Vuex object
- ``logging`` - our wrapper around the `loglevel logging module <https://github.com/pimterry/loglevel>`__
- ``CoreBase`` - a shared base Vue.js component (*CoreBase.vue*)
- ``kolibri-logging`` - our wrapper around the `loglevel logging module <https://github.com/pimterry/loglevel>`__
- ``AppBarPage`` - a shared Vue.js page component (*AppBarPage.vue*)

And **many** others. The complete specification for commonly shared modules can be found in ``kolibri/core/assets/src/core-app/apiSpec.js``. This object defines which modules are imported into the core object. These can then be imported throughout the codebase - e.g.:
The complete specification for commonly shared modules can be found in ``packages/kolibri/package.json``. The "exports" field defines the things inside the package that can be imported, and the "exposes" field defines additional modules that are bundled into the core package.

.. code-block:: javascript
import Vue from 'kolibri.lib.vue';
import CoreBase from 'kolibri.coreVue.components.CoreBase';
import Vue from 'vue';
import AppBarPage from 'kolibri/components/AppBarPage';
Adding additional globally-available objects is relatively straightforward due to the :doc:`plugin and webpack build system <frontend_build_pipeline>`.

To expose something in the core app, add the module to the object in ``apiSpec.js``, scoping it to the appropriate property for better organization - e.g.:

.. code-block:: javascript
components: {
CoreTable,
},
utils: {
navComponents,
},
These modules would now be available for import anywhere with the following statements:

.. code-block:: javascript
import CoreTable from 'kolibri.coreVue.components.CoreTable';
import navComponents from 'kolibri.utils.navComponents';
.. note::

In order to avoid bloating the core api, only add modules that need to be used in multiple plugins.
In general, code should not be added to the kolibri package unless it has been specified as required in planned work. This is to avoid cluttering the core package with unnecessary code.

Styling
-------
Expand All @@ -53,7 +35,7 @@ To help enforce style guide specs, we provide global variables that can be used
Dynamic core theme
------------------

Vuex state is used to drive overall theming of the application, in order to allow for more flexible theming (either for accessibility or cosmetic purposes). All core colour styles are defined in Javascript variables kept in Vuex state, which are then applied inline to elements using Vue.js style bindings from Vuex getters.
Reactive state is used to drive overall theming of the application, in order to allow for more flexible theming (either for accessibility or cosmetic purposes). All core colour styles are defined in Javascript variables kept in state, which are then applied inline to elements using Vue.js style bindings.

There are two cases where dynamic styles cannot be directly applied to DOM elements:
- inline styles cannot apply `pseudo-classes <https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes>`__ (e.g. ':hover', ':focus', '::before')
Expand All @@ -65,10 +47,7 @@ In order to apply a style using a computed class, define a style object as a com

.. code-block:: javascript
import themeMixin from 'kolibri.coreVue.mixins.themeMixin';
export default {
mixins: [themeMixin],
computed: {
pseudoStyle() {
return {
Expand Down
73 changes: 37 additions & 36 deletions docs/frontend_architecture/single_page_apps.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,46 +38,47 @@ If you want to expose your new single page app as a top level navigation item in
For more information on using `bundle_id` and connecting it to the relevant Javascript entry point read the documentation on the :ref:`Frontend build pipeline`. The entry point for the nav item should minimally do the following:

.. code-block:: html
.. code-block:: js
<template>
import { registerNavItem } from 'kolibri/composables/useNav';
import urls from 'kolibri/urls';
import { coreStrings } from 'kolibri/uiText/commonCoreStrings';
import baseRoutes from '../routes/baseRoutes';
import { learnStrings } from './commonLearnStrings';
<CoreMenuOption
:label="$tr('label')"
:link="url"
icon="learn"
/>

</template>


<script>
import CoreMenuOption from 'kolibri.coreVue.components.CoreMenuOption';
import navComponents from 'kolibri.utils.navComponents';
import urls from 'kolibri.urls';
const component = {
name: 'ExampleSideNavEntry',
components: {
CoreMenuOption,
},
computed: {
url() {
return urls['kolibri:kolibri.plugins.example:example']();
registerNavItem({
get url() {
return urls['kolibri:kolibri.plugins.learn:learn']();
},
get routes() {
return [
{
label: coreStrings.$tr('homeLabel'),
icon: 'dashboard',
route: baseRoutes.home.path,
name: baseRoutes.home.name,
},
},
priority: 5,
$tr: {
label: 'Example',
},
};
navComponents.register(component);
export default component;
{
label: coreStrings.$tr('libraryLabel'),
icon: 'library',
route: baseRoutes.library.path,
name: baseRoutes.library.name,
},
{
label: coreStrings.$tr('bookmarksLabel'),
icon: 'bookmark',
route: baseRoutes.bookmarks.path,
name: baseRoutes.bookmarks.name,
},
];
},
get label() {
return learnStrings.$tr('learnLabel');
},
icon: 'learn',
bottomBar: true,
});
</script>
This will create a navigation component which will be registered to appear in the navigation side bar.

Expand Down
4 changes: 2 additions & 2 deletions docs/frontend_architecture/testing_layout.rst
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,10 @@ It any composable does not have an associated mock file, please do create one be
.. code:: javascript
import useUser, { useUserMock } from 'kolibri.coreVue.composables.useUser';
import useUser, { useUserMock } from 'kolibri/composables/useUser';
import YourSampleComponent from '../YourSampleComponent.vue';
jest.mock('kolibri.coreVue.composables.useUser');
jest.mock('kolibri/composables/useUser');
...
Expand Down
4 changes: 2 additions & 2 deletions docs/i18n.rst
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ In order to translate strings in Javascript source files, the namespace and mess

.. code-block:: javascript
import { createTranslator } from 'kolibri.utils.i18n';
import { createTranslator } from 'kolibri/utils/i18n';
const name = 'someModule';
const messages = {
helloWorld: 'Hello world',
Expand Down Expand Up @@ -225,7 +225,7 @@ Content rendererers

User interfaces that are tightly coupled to embedded content, such as the 'next page' and 'previous page' buttons in a book, need to be flipped to match the language direction of that content. UIs that are not tightly integrated with the content should match the overall application language, not the content.

Information about content language direction is available in the computed props ``contentDirection`` and ``contentIsRtl`` from ``kolibri.coreVue.mixins.contentRendererMixin``. These can be used to change styling and directionality dynamically, similar to the application-wide ``isRtl`` value.
Information about content language direction is available in the computed props ``contentDirection`` and ``contentIsRtl``. These can be used to change styling and directionality dynamically, similar to the application-wide ``isRtl`` value.

In situations where we are using third-party libraries it might be necessary to flip the entire content renderer UI automatically using the RTLCSS framework rather than make targeted changes to the DOM. To handle these cases, it's possible to dynamically load the correct CSS webpack bundle using a promise:

Expand Down

0 comments on commit 5b50afb

Please sign in to comment.