Ever since we started bundling the app with webpack, there’s been less and less overlap between our ‘static’ directory (files belonging to the frontend app) and Django’s interpretation of the ‘static’ directory (files served directly to the web). Split the app out to its own ‘web’ directory outside of ‘static’, and remove all the custom collectstatic --ignore rules. This makes it much clearer what’s actually being served to the web, and what’s being bundled by webpack. It also shrinks the release tarball by 3%. Signed-off-by: Anders Kaseorg <anders@zulip.com>
1.9 KiB
UI: input pills
This is a high level and API explanation of the input pill interface in the frontend of the Zulip web application.
Setup
A pill container should have the following markup:
<div class="pill-container">
<div class="input" contenteditable="true"></div>
</div>
The pills will automatically be inserted in before the ".input" in order.
Basic usage
var $pill_container = $("#input_container");
var pills = input_pill.create({
$container: $pill_container,
create_item_from_text: user_pill.create_item_from_email,
get_text_from_item: user_pill.get_email_from_item,
});
You can look at web/src/user_pill.js to see how the above
methods are implemented. Essentially you just need to convert
from raw data (like an email) to structured data (like an object
with display_value, email, and user_id for a user), and vice
versa. The most important field to supply is display_value.
For user pills pill_item.display_value === user.full_name.
Typeahead
Pills almost always work in conjunction with typeahead, and
you will want to provide a source function to typeahead
that can exclude items from the prior pills. Here is an
example snippet from our user group settings code.
source: function () {
return user_pill.typeahead_source(pills);
},
And then in user_pill.js...
export function typeahead_source(pill_widget) {
const persons = people.get_realm_users();
return filter_taken_users(persons, pill_widget);
}
export function filter_taken_users(items, pill_widget) {
const taken_user_ids = get_user_ids(pill_widget);
items = items.filter((item) => !taken_user_ids.includes(item.user_id));
return items;
}
onPillCreate and onPillRemove methods
You can get notifications from the pill code that pills have been created/remove.
pills.onPillCreate(function () {
update_save_state();
});
pills.onPillRemove(function () {
update_save_state();
});